views:

191

answers:

6

Hello, I have a question regarding inheritance in Java. If I have this base class

class Parent {

    private String lastName;

    public Parent() {
        lastName = "Unassigned";
    }

    public String getLastName( ) {
        return lastName;
    }

    public void setLastName(String name) {
        lastName = name;
    }
}

And this subclass

class Child extend Parent {

        private String surName;

        public Child(String name) {
         surName = name;
        }

        public void setFullName(String first, String last) {
         surName = first;
         ..... = last;
        }

}

I want to make a method now in the subclass which can change both surname and lastname in a method. So I wonder how I can the private member lastname which is to be found in the base class. Should I use the setLastName() method which is inherit, or can I access the variable without having going through that way?

I also have question regarding if I was to override the setLastName() method in baseclass. How do I access the private member lastname which is in the baseclass then?

+10  A: 

You cannot access private members from an inherited class. You can either make them protected or use the setter (the latter one is preferable in my view).

You can override setLastName() in the inherited class and change the private member using the setter of the base class by means of the "super"-keyword (super.setLastName("something")).

Johannes Stiehler
what about if I want to override the method?How should I access the lastname then, change the member to protected?
starcorn
Cf. the second paragraph of my answer for that problem.
Johannes Stiehler
ic, thanks for the information ^^
starcorn
You should ask yourself why you want to override the method if you are using the same member.
Fortega
@Fortega, it was just an example so I could ask my question. But thanks for the advice :)
starcorn
+2  A: 

You should call the setLastName method.

 public void setFullName(String first, String last) {
    surName = first;
    setLastName(last);
 }

Or you could make the lastName in the Parent class protected. In that case, you can use it like this in the Child class:

public void setFullName(String first, String last) {
    surName = first;
    lastName = last;
 }

You cannot access a private member of the Parent class from the Child class.

Fortega
A: 

As a rule of thumb: always declare class members private and access them through methods (getter/setter in the easiest way) always. The only reason, I deviated from this rule so far is: lazyness...

for your additional question: override setLastName like this:

@Override
public void setLastName(String lastName) {
  doSomethingSpecial(lastName);      
  super.setLastName(lastName);
  doSomethingElse();      
}

(if you don't have to do something child-specific in the setter, you don't have to implement it as the parents implementation is visible for the child class in your case)

Andreas_D
A: 

Having a private field with public accessors is called encapsulation.

If you encapsulate a field, all other classes (including subclasses) must use the accessors to access the field. This is considered good practice because it allows you to change the internal implementation without any change to code that uses your class. Imagine how useful this is when other people's code (that you are maybe even not aware of) uses you code and can still use your code after you change your internal representation.

Most things we do when writing code, is to make software evolution less painful.

So in your case, you would write

class Child extends Parent {
  private String surName;
  public Child(String name) {
    surName = name;
  }
  public void setFullName(String first, String last) {
    surName = first;
    this.setLastName(last);
  }
  @Override
  public void setLastName(String last) {
    // ...
    super.setLastName(last);
    // ...
  }
}
Adrian
A: 

I would say that you do not need the surName property because one's surname is one's last name.

Edd
+1  A: 

If you encounter such clashes in semantics or naming within an inheritance hierarchy, you should re-evaluate your design. In most cases straight subclassing is not needed, and creates a for too tight coupling. If names are clashing, chances are that you are violating the so-called Liskov substitution principle (LSP). See also http://stackoverflow.com/questions/1030521/is-deriving-square-from-rectangle-a-violation-of-liskovs-substitution-principle

Adriaan Koster