Struggling On A Lesson About Classes & Subclasses of CodeHS - java

I spent two days in class trying to figure it out, but I just don't understand some of the errors.
I actually found a similar question in this site but I still don't get it.
The lesson's name is 4.12.4 Clothing Store.
In this problem, you’ll design a few classes that represent different
pieces of clothing in a clothing store.
You’ll write the classes for TShirt, Jeans, Sweatshirt and Clothing.
The Clothing class should have two instance variables: one for the
size of the clothing (a String), and another for the clothing’s color
(also a string).
Clothing should have two accessor (getter methods) as well:
public String getSize()
public String getColor()
The Sweatshirt class should have a private instance variable (or
field) to store whether or not it has a hood, and a corresponding
getter method
public boolean hasHood()
The TShirt class should have a private field to store the fabric and a
corresponding getter for that called
public String getFabric()
All Jeans should have the color blue.
The constructors should be of this format:
public Clothing(String size, String color)
public TShirt(String size, String color, String fabric)
public Sweatshirt(String size, String color, boolean hasHood)
public Jeans(String size)
And the following is my code:
public class Clothing
{
public String size;
public String color;
public Clothing(String size, String color)
{
this.size = size;
this.color = color;
}
public String getSize()
{
return size;
}
public String getColor()
{
return color;
}
}
public class TShirt extends Clothing
{
private String fabric;
public TShirt(String size, String color, String fabric)
{
super(size, color);
this.fabric = fabric;
}
public String getFabric()
{
return fabric;
}
}
public class Sweatshirt extends Clothing
{
private boolean hasHood;
public Sweatshirt(String size, String color, boolean hasHood)
{
super(size, color);
this.hasHood = hasHood;
}
public boolean getHasHood()
{
return this.hasHood;
}
}
public class Jeans extends Clothing
{
public Jeans(String size)
{
super(size);
}
}
My error:
Errors: Jeans.java: constructor Clothing in class Clothing cannot be
applied to given types;
Grader.java: You may have forgotten to declare hasHood() or it's out
of scope

Jeans passes just one argument to the super constructor. You don't have a one-argument constructor for Clothing. Either make Clothing(String size) or your Jeans class can pass a default value to the super. Like super(size, "Blue") or whatever is appropriate.
EDIT:
Change getHasHood() to hasHood(). Your class is enforcing naming conventions on you.

Related

Constructor Chaining with subclasses in Java

Just a question RE: Constructor Chaining in subclasses that I can't find a good answer on and I'm confusing myself a bit with.
I'm making a basic little Text Based RPG for some practice and I'm going through my constructors for an abstract class and have the constructors from 0-4 params chained together like below
abstract class Creature {
// Fields
private String name;
private int lifeForce;
private int strength;
private int agility;
// Constructors + Chaining
public Creature() {
this("Unknown")
}
public Creature(String name) {
this(name, 100);
}
public Creature(String name, int lifeForce) {
this(name, lifeForce, 10);
}
public Creature(String name, int lifeForce, int strength) {
this(name, lifeForce, strength, 10);
}
public Creature(String name, int lifeForce, int strength, int agility) {
this.name = name;
this.lifeForce = lifeForce;
this.strength = strength;
this.agility = agility;
}
My confusion is how best to format the constructors of a subclass of creature, for example this simple Person class introduces two new fields. There's definitely too much repetition if I write the constructors like this
// Constructors + Chaining
public Person() {
super("Unknown");
this.skillClass=new Mage();
this.dialogue="...";
}
public Person(String name) {
super(name);
this.skillClass=new Mage();
this.dialogue="...";
} etc etc etc
I suppose I could restrict the constructors to limit the repetition but I'm mostly just wondering if there's good best practice that I'm missing here.
Any and all suggestions welcome and if anyone has any good resources to recommend that go deeper than the usual
Class B extends Class A
examples I'd massively appreciate.
In situations like this one when you need to use multiple constructors with different parameters, it is recommended to use the builder pattern like this :
abstract class Creature {
// Fields
private String name;
private int lifeForce;
private int strength;
private int agility;
private Creature(Builder<?> builder) {
this.name = builder.name;
this.lifeForce = builder.lifeForce;
// Add the other attributes here.
}
public static abstract Builder extends Builder<T extends Builder<T>> {
private String name;
private int lifeForce;
private int strength;
private int agility;
public Builder(//here you put the attributes that you need to have in all instances) {
// here you do the affectations.
}
// now you need to make the functions that set each property :
public Builder lifeForce(int lifeForce) {
this.lifeForce = lifeForce;
return this;
}
// you do the same thing for all the other attributes.
...
public Creature build() {
return new Creature(this);
}
}
}
So for the explanation : This pattern will allow you to create instances of your class by setting only the needed attributes.
As here you have subclasses the builder pattern will be little bit more harder to understand but it is the perfect solution in such situation.
We need to apply the builder pattern also for every subclasse so let's do it for the person class :
public class Person extends Creature {
private int anotherField;
public Person(Builder builder) {
super(builder);
this.anotherField = anotherField;
}
public static Builder extends Creature.Builder<Builder> {
public Builder(//add the fieldHere if it is needed in all class instances) {
// if the field is not mandatory you can omit this constructor but you need to put the function below.
}
public Builder anotherField(int anotherField) {
this.anotherField = anotherField;
}
public Person build() {
return new Person(this);
}
}
Now let me show you how tricky is this solution :
1/ declare person with 2 fields :
Person p1 = Person.Builder().name("name").anotherField(0).build();
2/ declare another one with just one field
Person p2 = Person.Builder().agility(1000).build();
Remark : In these two examples, i supposed that your builders' constructors don't have parameters. If for example the name is mandatory field :
Person p3 = Person.Builder("name").anotherField(0).build();
I wish that you had the idea about using builder pattern.

Mapping complex data from Model to View

Let's consider a simplified MVC architecture, where Model operates on different types of Confections. There are different subtypes of Confection class, such as Candy, Cookie, Doughnut, etc. Every subtype, in turn, has different sets of properties, like size, color, shape and so on.
For instance, that's one implementation of Candy class:
class Candy extends Confections {
public enum Size {
LARGE,
MEDIUM,
SMALL,
}
public enum Color {
RED,
GREEN,
YELLOW,
}
private Size size;
private Color color;
...
}
Now the Model wants to update the View with a new set of Confections to display. Let's say that the only thing View needs to get the picture of a Confection is a string representation of its type and properties, e.g. "candy_red_large". The dumbest thing to do this is to have a number of instanceof branches and switches for types inside the View:
if (confection instanceof Candy) {
result.append("candy");
switch ((Candy) (confection).color) {
case RED:
result.append("_red");
break;
...
}
...
} else ...
Besides this monster is large and ugly, it also doesn't benefit from encapsulation and OOP. Let's consider a better way of doing this by providing each Confection subclass with a method like toString(), which will return the desired string representation:
class Candy extends Confections {
...
public String toString() {
return ("candy_" + size + "_" + color).toLowerCase();
}
}
The only problem I see in this approach is some kind of architectural "trade-off" when Model is actually aware of View implementation details having toString method, which is useless from Model's point of view.
What would be the best approach or design patterns to use in such case for mapping diverse data from Model to View representation?
maybe use some to strings to get what you want:
class Confections {}
class Candy extends Confections {
public enum Size {
LARGE,MEDIUM,SMALL,
}
public enum Color {
RED,GREEN,YELLOW,
}
Candy(Size size,Color color) {
this.color=color;
this.size=size;
}
private Size size;
#Override public String toString() {
return "Candy [size="+size+", color="+color+"]";
}
public String toString2() {
return "candy_"+size+"_"+color;
}
private Color color;
}
public class SO53564342_mapping_complex_data_from_model_to_view {
public static void main(String[] args) {
Candy candy=null;
for(Candy.Size size:Candy.Size.values())
for(Candy.Color color:Candy.Color.values())
System.out.println((candy=new Candy(size,color)).toString()+" "+candy.toString2());
}
}
Idea
I could imagine to introduce a new interface StringRepresentation:
public interface StringRepresentation {
String represent();
}
StringRepresentation will be implemented by Confections. To foce every child of Confections to implement represent make it abstract:
public abstract class Confections implements StringRepresentation {}
After that we have to implement in Candy and the other classes represent. If you want to work with Enums you could let them implement StringRepresentation too.
Example of a String Representation in Candy
public class Candy extends Confections {
private Size size;
private Color color;
public String represent() {
return "candy_" + color.represent() + "_" + size.represent();
}
public enum Size implements StringRepresentation {
LARGE("large"),
MEDIUM("medium"),
SMALL("small");
private final String representation;
Size(String representation) {
this.representation = representation;
}
public String represent() {
return this.representation;
}
}
public enum Color implements StringRepresentation {
RED("red"),
GREEN("green"),
YELLOW("yellow");
private final String representation;
Color(String representation) {
this.representation = representation;
}
public String represent() {
return this.representation;
}
}
}
Benefit
You do not need to use conditions like switch or if and you do not need loops. In addition, each class/component - as above the enums and classes - has its own logic, so you know where to change a representation as you change in the future.

Static factory method does not work

Started reading "Effective java" and can't understand why it doesn't work for me when I try coding an example..
Compile error:
Error:(12, 16) java: constructor Car in class Car cannot be applied to
given types;
public class Car {
String model;
//no private constructor
public static Car fromModel(String model) {
return new Car(model);
}
}
Here everything is OK:
public class Car {
String model;
//no private constructor
public static Car fromModel(String model) {
return new Car(model);
}
}
//Here everything is OK:
public class Car {
String model;
private Car(String model) {
this.model = model;
}
public static Car fromModel(String model) {
return new Car(model);
}
}
Why should I generate constructor if "Consider static factory methods instead of constructors" ???
"Consider static factory methods instead of constructors" refers to providing access to instantiation of your objects to users of your library outside your class.
The constructor that your factory method uses is an implementation detail of your factory method in the same way as the static public method - the method and the private constructor together constitute one factory method for outside users of your class library.
Your example may be very simple. Plain constructor may have either large number of parameters. In such cases you could "name" each constructor by creating a static constructor method. Secondly using this pattern you could hide part of constructor parameters.
Example:
class FinishEvent {
privare Car response;
private boolean success;
private String errorMessage;
//private constructor, we delegate creating to named methods
private FinishEvent(Car response, boolean success, String errorMessage) {... }
}
As you can see Car is an response here, but when Event is a success, we don't need errorMessage to be filled. On the other hand, if the process is failed, we don't have a response to fill in.
Here static constructor methods come in handy:
public static FinishEvent success(Car response){
return new Car(response, true, null);
}
public static FinishEvent failed(String errorMessage){
return new Car(null, false, errorMessage);
}
Having this API other users of your class, know how to use it.
If your Car would be an abstract method, then your factory methods could provide implementations. That way you could hide all implementations from user, but provide a way to create them.
The answer for me is that I need at least one private constructor to make several static methods.
No compilation errors:
public class Car {
String model;
String color;
String modelYear;
private Car(String model, String color, String modelYear) {
this.model = model;
this.color = color;
this.modelYear = modelYear;
}
public static Car fromModelAndColor(String model, String color){
return new Car(model, color, null);
}
public static Car fromModelAndYear(String model, String modelYear){
return new Car(model, null, modelYear);
}
public static Car fromModelAndColorAndYear(String model, String color, String modelYear){
return new Car(model, color, modelYear);
}
}

Looping over heterogeneous collection

The example is as follows: I have a Box that needs to be filled with some Things. I'm interested only in weight of each thing. Also, beside weight, I need to correctly identify the thing that I'm measuring. Each thing type has different Id type. In this case I have toys and fruits, which have ToyId and FruitId respectively. In the end, I need to be able to print thing identifier and thing weight.
Question: Is it somehow possible to access specific methods on ThingIds without using instanceof operator (as in example)?
class Color{}
interface ThingId {}
class FruitId implements ThingId {
String name; //"apple", "orange", ...
FruitId(String name){ this.name = name; }
String getName(){ return this.name; }
}
class ToyId implements ThingId {
String shape; //"square", "circle", ...
Color color; //"red", "blue"...
ToyId(String shape, Color color){ this.shape = shape; this.color = color; }
String getShape(){ return this.shape; }
Color getColor(){ return this.color; }
}
class Thing{
ThingId thingId;
Integer weight;
public Thing(ThingId thingId, Integer weight){
this.thingId = thingId;
this.weight = weight;
}
ThingId getThingId(){ return this.thingId; }
Integer getWeight(){ return this.weight; }
}
class Box {
Set<Thing> things = new HashSet<>();
void addThing(Thing thing){
this.things.add(thing);
}
Collection<Thing> getThings(){
return this.things;
}
}
class Program {
public static void main(String[] args) {
FruitId appleId = new FruitId("apple");
Thing apple = new Thing(appleId, 1);
ToyId cubeId = new ToyId("square", new Color());
Thing cube = new Thing(cubeId, 22);
Box box = new Box();
box.addThing(apple);
box.addThing(cube);
for(Thing t : box.getThings()){
System.out.print("Thing Id is: ");
if(t.getThingId() instanceof FruitId) { //any other possibility than using instance of?
process((FruitId)t.getThingId());
}
if(t.getThingId() instanceof ToyId){ //any other possibility than using instance of?
process((ToyId)t.getThingId());
}
System.out.println("Weight is : " + t.getWeight());
}
}
static void process(FruitId fruitId){
System.out.println(fruitId.getName());
}
static void process(ToyId toyId){
System.out.println(toyId.getShape() + toyId.getColor());
}
}
UPDATE
OK, I think Visitor pattern could be useful here:
class Color{}
interface ThingId {
void visitThingId(ThingIdVisitor visitor);
}
class FruitId implements ThingId {
String name; //"apple", "orange", ...
FruitId(String name){ this.name = name; }
String getName(){ return this.name; }
#Override
public void visitThingId(ThingIdVisitor visitor) {
visitor.process(this);
}
}
class ToyId implements ThingId {
String shape; //"square", "circle", ...
Color color; //"red", "blue"...
ToyId(String shape, Color color){ this.shape = shape; this.color = color; }
String getShape(){ return this.shape; }
Color getColor(){ return this.color; }
#Override
public void visitThingId(ThingIdVisitor visitor) {
visitor.process(this);
}
}
class Thing{
ThingId thingId;
Integer weight;
public Thing(ThingId thingId, Integer weight){
this.thingId = thingId;
this.weight = weight;
}
ThingId getThingId(){ return this.thingId; }
Integer getWeight(){ return this.weight; }
}
class Box {
Set<Thing> things = new HashSet<>();
void addThing(Thing thing){
this.things.add(thing);
}
Collection<Thing> getThings(){
return this.things;
}
}
class ThingIdVisitor{
void process(FruitId fruitId){
System.out.println(fruitId.getName());
}
void process(ToyId toyId){
System.out.println(toyId.getShape() + toyId.getColor());
}
}
class Program {
public static void main(String[] args) {
FruitId appleId = new FruitId("apple");
Thing apple = new Thing(appleId, 1);
ToyId cubeId = new ToyId("square", new Color());
Thing cube = new Thing(cubeId, 22);
Box box = new Box();
box.addThing(apple);
box.addThing(cube);
for(Thing t : box.getThings()){
System.out.print("Thing Id is: ");
t.getThingId().visitThingId(new ThingIdVisitor());
System.out.println("Weight is : " + t.getWeight());
}
}
}
I don't really get what you're trying to achieve. First of all, I don't get the use of the interface ThingId. Second, I think you're a bit confused about interfaces and inheritance. If I were you, I'd look up polymorphism.
Anyway, I propose you remove the ThingId interface and let the FruitId and ToyId classes extend the Thing class. As your collection only exists of Things, and as your Fruit and Toy classes all extend this Thing class and thus implement the getWeight() method, you should not use instanceof anymore.
But please, read up on polymorphism.
your interface ThingId must provide the respective methods that you want to have.
If you simple want to print out information, then you can use like a simple
public String getInformation();
Then the implementations can return the information that is relevant for them and you can simply work with ThingId in your application code.
BTW: As you are storing your Things in a HashSet make sure to implement equals and hashCode in all Thing implementations
Also I dont really see, why you need a Thing and a ThingId, as ThingId seems a bit more than a simple id and actually a thing. So for me it seems that ThingId is redundant and all can be achieved by the having different Things
Since you are calling the same method process on both the instance types, why not add that method to ThingId interface itself.
By doing so, you could just call:
t.getThingId().process();
Instead of finding the instance type and calling respective methods.

How to have all parent classes in one grandparent class without gaining all attributes of grandparent class?

I am rather new to Java, rather only a week's worth of learning so I am still very inexperienced. I have spent a few days on polymorphism and know that I can extend a parent class to a child class, but I would like to know how to have a grandparent class have all the attributes of the parent classes. I have done a bit of research but haven't found what I was looking for. What I am working on is creating objects of clothing. I have one grandparent which is 'Clothing' three parents 'Upper_wear', 'Lower_wear', and 'Shoes' with many children such as 't-shirts', 'shorts' and 'sandals'. Currently what I have in the parents code is:
public class Upper_wear
{
private String fabric;
private int numb_zippers;
private String draw_string;
private int numb_pockets;
private int size;
private String color;
private double length_sleeves;
private int length_shirt;
private String collar;
private String hood;
private int code;
private double price;
private String name;
Upper_wear(String fabric,int numb_zippers,String draw_string,int numb_pockets,int size,String color, double length_sleeves, int length_shirt, String collar, String hood, int code, double price, String name){
this.fabric = fabric;
this.numb_zippers = numb_zippers;
this.draw_string = draw_string;
this.numb_pockets = numb_pockets;
this.size = size;
this.color = color;
this.length_sleeves = length_sleeves;
this.length_shirt = length_shirt;
this.collar = collar;
this.hood = hood;
this.code = code;
this.price = price;
this.name = name;
}
public String get_fabric(){
return fabric;
}
public int get_numb_zippers(){
return numb_zippers;
}
public String get_draw_string(){
return draw_string;
}
public int get_numb_pockets(){
return numb_pockets;
}
public int get_size(){
return size;
}
public String get_color(){
return color;
}
public double get_length_sleeves(){
return length_sleeves;
}
public int get_length_shirt(){
return length_shirt;
}
public String get_collar(){
return collar;
}
public String get_hood(){
return hood;
}
public int get_code(){
return code;
}
public double get_price(){
return price;
}
public String get_name(){
return name;
}
}
And for the children's code I have:
public class Jacket extends Upper_wear
{
Jacket(String fabric,int numb_zippers,String draw_string,int numb_pockets,int size,String color, double length_sleeves, int length_shirt, String collar, String hood, int code, double price, String name){
super(fabric, numb_zippers, draw_string, numb_pockets, size, color, length_sleeves, length_shirt, collar, hood, code, price, name);
}
}
The reason why I don't just extend clothing with all the variables is because I don't want to state if or not 'Upper_wear' has 'Shoe_laces' which is a variable in 'Shoes'. Yet, I want to gather all parent classes into one because when I go to the run class. In the for loop, I want to list out the prices of every item of Clothing and not just of a parent class. I feel that I am limited to only iterating through one parent class at a time such as what I currently have:
public class Run
{
public static void main (String[]args){
Shoes Tennis_shoes_01 = new Shoes("Canvas", 0, "yes", 10, "red and white", 0,0.5,2.5, 00001, 750.99,"Tenny shoey");
Upper_wear T_shirt_01 = new Upper_wear("Cotton", 0, "no", 0, 14, "yellow", 14.5, 15, "v-neck", "no", 00002, 990.50, "Yel-ow");)
Shoes[]In_Stock = {Tennis_shoes_01};
Upper_wear[]In_Stock_upper = {};
Lower_wear[]In_Stock_lower = {};
System.out.println("Price");
System.out.println("-------");
for(Shoes x : In_Stock){
System.out.println(x.get_name() + ": " +x.get_price());
}
for(Upper_wear x : In_Stock_upper){
System.out.println(x.get_name() + ": " + x.get_price());
}
}
What I am wanting is something more like this:
public class Want_run
{
public static void main(String[]args){
Clothing Tennis_shoes_01 = new Shoes("Canvas", 0, "yes", 10, "red and white", 0,0.5,2.5, 00001, 750.99,"Tenny shoey");
//Not sure if this is possible to have a class that's different than the constructor but I am looking for it to come from clothing class with properties of Shoes.
Clothing T_shirt_01 = new Upper_wear("Cotton", 0, "no", 0, 14, "yellow", 14.5, 15, "v-neck", "no", 00002, 990.50, "Yel-ow");
//So I want all properties to be in clothing but the ones that the childeren don't have I want to be just blank.ex. Upper_wear is blank on the shoe_laces.
Clothing[]In_Stock = {Tennis_shoes_01, T_shirt_01};
//I really want everything to be just in one list to iterate through but I can't currently do that with multiple parents of my knowledge.
for(Clothing x : In_Stock){
System.out.println(x.get_name() + ": " + x.get_price());
}
//this way I have only one for loop for every item,and for parents that don't have 'price' I am hoping would just not print.
}
}
So I want clothing to have every attribute of 'Upper_wear', 'Lower_wear', and 'Shoes', but not the parents to have every attribute of Clothing. Such that the attributes that are specific to Shoes, I wish to be blank for the other two parents when it iterates through methods specific to Shoes. I'm not sure if what I am looking for is even possible to do. If you cannot understand what I am looking for, I am sorry for being confusing. Thank you for taking your time to read this and helping me.
What you are trying to do is a classic application of polymorphism. You just need to clarify a few concepts.
Your grand parent will contain all the attributes that are common to all children, such as item ID, name, colour(s), price, etc. It should also contain common functions, such as a print() function which is what you require in your main.
All children (including parents) will introduce their specific attributes in their classes, such as hood/collar for uppers, and inner lining for jacket. They will also override (provide their own implementation of) functions they need to customize according to their needs. So, in your case, while the Clothing will have a print() function, each sub class will have its own implementation of it, in which it will print all its own properties such as number of zippers, shoelaces.
Finally, in your main, you will have a list of type Clothing, which will contain references to objects of all types you want. A parent can point to an object of a child type. For example,
Clothing c = new Jacket(...);
c.print(); // This will call the print() of class Jacket, not Clothing
I suggest reading up on dynamic polymorphism. This link contains a quick introduction and a nifty example.

Categories

Resources