views:

1171

answers:

3

Hi, I was wondering if there's a language feature in Java in which methods of a superclass would be invisible for members of a subclass:

 public class Subclass extends protected Superclass

or something. I'll give an example.

Here is your superclass.

public class A{
    public String getA(){...}
    public String getB(){...}
    public String getC(){...}
    public void setA(String a){...}
    public void setB(String b){...}
    public void setC(String c){...}
}

If you want to subclass A while protecting some of its methods, and you can't change access modifyers in methods unless you override them, you'd end up with something like this-

public class B extends A{
    private String getA(){return super.getA();}
    private String getB(){return super.getB();}//These four methods have
    private void setA(String a){super.setA(a);}//to be redeclared.
    private void setB(String b){super.setB(b);}

    public String getC(){return super.getC();}//These two methods can be
    public void setC(String c){super.setC(c);}//removed.
    public String getD(){...}
    public void setD(String d){...}
}

Either that or you can keep a private instance of A and have something like this:

public class B{

    private A obj;

    private String getA(){return obj.getA();}
    private String getB(){return obj.getB();}//These four methods can also
    private void setA(String a){obj.setA(a);}//be removed.
    private void setB(String b){obj.setB(b);}

    public String getC(){return obj.getC();}//These two methods are
    public void setC(String c){obj.setC(c);}//redeclared.
    public String getD(){...}
    public void setD(String d){...}
}

Can you have something that takes both in a way that you don't have to redeclare any methods?

+6  A: 

There is no "non-public" inheritance in Java, unlike the situation in C++.

Inheritance creates a subtyping relation. Any instance of B is also an instance of A, and should respond to the same messages. If instances of B clearly don't respond to all messages that instances of A respond to, then inheritance would be inappropriate anyway.

Your last solution (B does not inherit from A) is the appropriate one: you don't create a subtyping relation, just use one type to (secretly) implement the other.

Uri
+1 for comparison with C++ (which has protected and private inheritance).
Chris Jester-Young
When I used to teach advanced C++, I used to draw venn diagrams to show subtyping relations, and show what is seen inside and outside the subclasses, found it very effective to demonstrate the concept. However, I felt that often it was more trouble than it was worth.
Uri
+2  A: 

Other than setting the fields/methods to private in the superclass, I don't think there is a way around this.

I think your best best would be your second option, where class B holds a private reference to class A.

Andy White
+3  A: 

I don't think it is or should be possible.

If you use inheritance so that B extends A, you should be able to use a B object as an A object. For instance, this would be possible:

A obj = new B();

Now the program has no way of knowing that you can't call some of A's public methods.

And without inheritance, redefinition of functions is unavoidable.

Jordi