2015-11-13 2 views
4

Я знаю, чтоRestricted наследование в Java

class A { } 
class B extends A { } 
class C extends B { } 

является абсолютно законным, и я могу

C obj = new C(); 
obj.anyMethodfromA(); 

возможно. Теперь вопрос в том, что, если я не хочу получать класс A методов в класс C только класс B методы должны наследоваться. Возможно ли это?

C anotherObj = new C(); 
anotherObj.anyMethodfromA(); //can be illegal? 
anotherObj.anyMethodfromB(); //should be legal. 
+1

Это возможно только в том случае, если 'B' не расширяет' A'. Хотя вы можете переопределить методы 'A' в' C' и заставить их бросать 'UnsupportedOperationException', но это не сделает их незаконными для вызова во время компиляции. – marstran

ответ

6

Вы не можете удалять classA методы из classC, все, что вы можете сделать, это переопределить метод CLASSA в classC и бросить UnsupportedOperationException. например

class C extends B { 

    @override 
    public void someMethodWasInClassA() { 
     throw new UnsupportedOperationException("Meaningful message"); 
    } 

} 
+0

любая логическая причина для этого? – user137124

+3

Зачем вам это нужно? Извините, но у вас есть C is-a A. Если это не так, тогда не делайте этого. –

+0

Сторона примечания: Я предлагаю решение, это ужасная идея. Если вы когда-либо делаете это, вы заслуживаете боль и ужас, которые он причинит вам. –

0

В Java нет такого мелкозернистого наследования. После того, как вы отметили A методы protected, которые простираются вниз по всей иерархии.

Обходным путем было бы переопределить методы класса A в классе C, выбрасывая соответствующие исключения во время выполнения. Но вы не можете принудительно выполнить сбой времени компиляции.

(Обратите внимание, что вы могли бы достичь того, чего вы хотите в C++ с friend судов: вы бы отметить методы private в классе A и сделать класс Bfriend класса A.)

0

На данный момент C is-a A , но похоже, что вы этого не хотите. Таким образом, вместо того, чтобы иметь, что, может быть, C has-a B или B has-a A.

Prefer composition over inheritance.

+0

@mik Да, это должно быть лучшим решением, если OP соглашается изменить дизайн своей модели данных. – rajuGT

+0

Может ли разум нижестоящего объяснить, почему? –

1

Ограничение доступа для некоторых подклассов не представляется возможным. Вместо этого вы могли бы использовать интерфейсы, чтобы добавить определенную функциональность к определенному классу в дополнение к наследованию.

0

Вы можете использовать некоторую ловкость руки, используя interface, чтобы скрыть methodFromA, но вы не можете удалить ее.

class A { 

    public void methodFromA() { 
     System.out.println("methodFromA"); 
    } 
} 

class B extends A { 

    public void methodFromB() { 
     System.out.println("methodFromB"); 
    } 
} 

class C extends B { 
} 

interface D { 

    public void methodFromB(); 

} 

class E extends B implements D { 

} 

public void test() { 
    // Your stuff. 
    C obj = new C(); 
    obj.methodFromA(); 
    // Make a D 
    D d = new E(); 
    d.methodFromB(); 
    // Not allowed. 
    d.methodFromA(); 
    // Can get around it. 
    E e = (E) d; 
    e.methodFromA(); 
}