Защищенная структура классов в Java? - PullRequest
6 голосов
/ 12 апреля 2009

Мне было интересно, есть ли в Java функция языка, в которой методы суперкласса были бы невидимы для членов подкласса:

 public class Subclass extends protected 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){...}
}

Если вы хотите создать подкласс A, защищая некоторые из его методов, и вы не можете изменять модификаторы доступа в методах, если не переопределите их, вы получите что-то вроде этого:

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){...}
}

Либо так, либо вы можете сохранить частный экземпляр A и получить что-то вроде этого:

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){...}
}

Можете ли вы иметь что-то такое, что не требует переопределения каких-либо методов?

Ответы [ 3 ]

10 голосов
/ 12 апреля 2009

В Java нет «непубличного» наследования, в отличие от ситуации в C ++.

Наследование создает отношение подтипа. Любой экземпляр B также является экземпляром A и должен отвечать на те же сообщения. Если экземпляры B явно не отвечают на все сообщения, на которые отвечают экземпляры A, то наследование в любом случае будет неуместным.

Ваше последнее решение (B не наследует от A) является подходящим: вы не создаете отношение подтипа, просто используете один тип (тайно) для реализации другого.

3 голосов
/ 12 апреля 2009

Я не думаю, что это возможно или должно быть возможно.

Если вы используете наследование, так что B расширяет A, вы должны иметь возможность использовать объект B в качестве объекта A. Например, это было бы возможно:

A obj = new B();

Теперь у программы нет возможности узнать, что вы не можете вызвать некоторые из открытых методов А.

И без наследования переопределение функций неизбежно.

2 голосов
/ 12 апреля 2009

Кроме установки полей / методов в private для суперкласса, я не думаю, что есть способ обойти это.

Я думаю, лучшим вариантом будет ваш второй вариант, где класс B содержит частную ссылку на класс A.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...