Reputation: 1083
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
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
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
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
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