WoeIs
WoeIs

Reputation: 1083

I'm having problems fixing my "getters" and "setters" in inheritance

Please bear with me, this is my first time dealing with inheritance in Java. :)

I have the following superclass which identifies ships and returns a name of the ship and its length:

public class Ship {

    private String name="";
    private int length=0;

    public Ship(String name, int length) {
        this.setName(name);
        this.length = length;
    }

    public static String getName() {
        return name;
    }

    public void setName(String name) {
        Ship.name = name;
    }

    public String toString() {
        return " Ship "+name+" l="+ length ;
    }

}

This is done by creating an object such as:

Ship SSAnne = new Ship("S.S. Anne", 45);

Then I have "sub-classes" that extend from my superclass which define objects Container Ships, Tankers, and Cruise Ships. Here is my sub-class for container ships (the other types of ships are identical, except for different variable names):

public class ContainerShip extends Ship {

    private int teu=0;

    public ContainerShip(String string, int length, int teu) {
        super(getName(), length);
        this.teu = teu;
    }

    public void setName(String name) {
        ContainerShip.name = name;
    }

    public String toString() {
        return super.toString()+" container carrier with "+teu+" TEU";
    }

}

These sub-classes are called like this:

ContainerShip dave = new ContainerShip("Dave Oest", 100, 2000);

Where an extra variable is added and the first two arguments are the same variables from the superclass.

My issue is with my getters and setters for the "name" variable. When I run my code, it generates the "S.S. Anne" name for all objects, even the objects from the sub-classes. I can't seem to get it to "get" the name of the ships for my sub-classes.

Can anybody help me how to properly set up the getters and setters in my sub-classes?


@GBlodgett:

public class Ship {

    private String name="";
    private int length=0;

    public Ship(String name, int length) {
        this.setName(name);
        this.length = length;
    }

    public void getName(String name) {
        this.name = name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String toString() {
        return " Ship "+name+" l="+ length ;
    }

}

public class ContainerShip extends Ship {

    private int teu=0;

    public ContainerShip(String string, int length, int teu) {
        super(getName(), length);
        this.teu = teu;
    }

    public void getName(String name) {
        this.name = name;
    }

    public void setName(String name) {
            this.name = name;
    }

    public String toString() {
        return super.toString()+" container carrier with "+teu+" TEU";
    }

}

Upvotes: 0

Views: 245

Answers (4)

GBlodgett
GBlodgett

Reputation: 12819

You have declared name as static, which means there's only one copy shared among all instances of the class. You want to remove the static keyword, and then in your getters and setters, use the this keyword, which refers to the object the method is invoked on:

 public void setName(String name) {
    this.name = name;
}

In which case the setName method will be the same in both classes and you will not need to override it in the subclass


The first problem with your updated code is that you cannot refer to an instance method while explicitly invoking a constructor. Instead of calling getName(), pass the String argument you pass into the constructor:

public SubClass(String string, int length, int teu) {
    super(string, length);
    this.teu = teu;
}

Then in your getName() method, you are treating it as a setter. You should instead return the name field:

public String getName() {
    return this.name;
}

This leads to your last problem: You are using the superclass copy of name. Because you marked it as private, it will not be accessible to other classes. You can either give ContainerShip it's own name variable, or make the name in Ship protected, or use super again like:

public void setName(String name) {
    super.setName(name);
} 

Upvotes: 3

unarr
unarr

Reputation: 86

You dont need setters and getters in the sub-class for name and length values. Only if you want to override them.

Ship superclass

public class Ship {

    private String name;
    private int length;

    public Ship(String name, int length) {
        this.name = name;
        this.length = length;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String toString() {
        return " Ship "+name+" l="+ length ;
    }

}

ContainerShip subclass

public class ContainerShip extends Ship {

    private int teu;

    public ContainerShip(String string, int length, int teu) {
        super(string, length);
        this.teu = teu;
    }

    public String toString() {
        return super.toString()+" container carrier with "+teu+" TEU";
    }

}

Main method

public static void main(String[] args) {

        ContainerShip cont = new ContainerShip("Name", 100, 4);
        System.out.println(cont.getName());
        cont.setName("new name");
        System.out.println(cont.getName());
}

OUTPUT:

Name

new name

Upvotes: 0

elbraulio
elbraulio

Reputation: 994

You can use Interfaces to define Type and Abstract classes to define default behavior. For instance:

interface Ship {
    String getName();
    void setName();
}

abstract class DefaultShip implements Ship {
    private int length;

    public DefaultShip(int length) {
        this.length = length;
    }

    public String toString() {
        return " Ship " + getName() + " l=" + this.length;
    }
}

public class ContainerShip extends DefaultShip {

    private int teu;
    private String name;

    public ContainerShip(String name, int length, int teu) {
        super(length);
        this.name = name;
        this.teu = teu;
    }

    public void getName(String name) {
        return this.name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String toString() {
        return super.toString() +" container carrier with " + this.teu + " TEU";
    }
}

Upvotes: 0

Pushpesh Kumar Rajwanshi
Pushpesh Kumar Rajwanshi

Reputation: 18357

You can't access instance variables from static methods,

private String name="";
private int length=0;

These are instance variables, where as your method is declared as static

public static String getName() {

One key thing you should always remember while implementing inheritance.

Do not use static word with variable declaration or use static word in method declaration.

Inheritance only happens when we deal everything with instance variables and instance (non-static) methods. So you will have to change couple of things,

Change this,

public static String getName() {

to,

public String getName() {

Similarly, you can't access instance variables with class name and for referring to the current object, you can use this. Hence change,

public void setName(String name) {
    Ship.name = name;
}

to

public void setName(String name) {
    this.name = name;
}

Also, in this constructor you have a problem,

public ContainerShip(String string, int length, int teu) {
    super(getName(), length);
    this.teu = teu;
}

You aren't using string variable that is your first parameter. You need to change this super class from this,

super(getName(), length);

to,

super(string, length);

This way, whatever was passed to constructor, will get passed to constructor of super class.

You should fix these problems first.

Also, once you create an object using ContainerShip class, it will have access to getter/setter methods from parent class Ship as your sub class will inherit those methods which is called inheritance. Its a broad subject and as you proceed, you will know more such constructs. Let me know if you further have any query regarding inheritance.

As you have declared your instance variables in super class as private, your instance variables aren't visible directly to sub classes, and only available through public getter/setter, but in case you want to directly access them, you can declare them as protected and can directly access them. Inheritance is the reason you can access variables from super class in sub class provided they are not declared as private. Private means only accessible in its own class.

Upvotes: 1

Related Questions