user613857
user613857

Reputation:

How can I cancel certain functions while inheriting?

This is a fairly odd question that someone asked me recently and I couldn't think of a achieve this.

Let Person be a class with several public functions and attributed. Say one of the attributes is color of the eye, with two functions: getColor() and setColor().

Now let Teacher extend to Person to inherit it's properties.

Her question: What if I don't want to inherit getColor() and setColor() but the rest of the functions?

My initial thought was to @Override all of them and return void, doing nothing. However, I don't think this is safe or preferred method, maybe there is a more elegant solution?

Upvotes: 2

Views: 82

Answers (6)

Tony Hopkinson
Tony Hopkinson

Reputation: 20320

Don't use inheritance.

Break up your hierarchy so you have a base class with all the methods you do want to inherit, and then add the ones you don't in a descendant.

After that elegance, is a big fat bloke with a beard claiming to be Kierra Knightly...

Override and throw a NotImplementedException, with big comments all over the code, that say REFACTOR, at a push.

Upvotes: 0

Luis Casillas
Luis Casillas

Reputation: 30237

What you are asking for cannot be done in a "moral" sense so to speak: anything that you do to achieve this is something you shouldn't do. Why? Because subtypes are supposed to be usable everywhere their supertype is. This is called the Liskov Substitution Principle.

Think about it this way: when you define the Person class and specify that it has a getColor() and setColor() method, basically you are making a promise all of your class' users that if they have a Person reference, they can invoke methods with those names on it. And when you subclass Person to make the Teacher class, you are inheriting the same promise; somebody may refer to one of your Teacher objects through a Person reference, and thus you are bound to respect all the promises that the superclass makes.

You may also want to read about the Circle-ellipse Problem while you're at it—it's intimately related to what you're asking about.

Upvotes: 1

BRPocock
BRPocock

Reputation: 13914

That's essentially the definition of the “contract” of Person, by inheriting from Person, Teacher is “promising” to behave in that way.

Aside from refactoring Person to inherit from, say, interface PersonBase and interface PersonWithEyes, you're kinda stuck with “doing the right thing” in that context, if you want to present a sane implementation of Person to your callers.

Upvotes: 1

toto2
toto2

Reputation: 5326

That's bad. The whole point of inheritance is that all implementations of some interface (or subclasses of some class) have the same contract.

You would need to define a new interface. You might also consider shifting the whole design upside down such that the class without the methods is the superclass.

Upvotes: 2

Dave Newton
Dave Newton

Reputation: 160261

You can either make them private to the parent class, or override them. Making them private, of course, makes them useless outside of the parent class as well.

Another option is to use composition and delegation, and just don't pass on those methods--but you lose the is-a relationship unless you have very granular interfaces.

Upvotes: 1

Oliver Charlesworth
Oliver Charlesworth

Reputation: 272667

No, it doesn't make sense.

Consider that you could always do this:

class Person {
    public int getColor() { ... }
    public void setColor(int x) { ... }
}

class Teacher extends Person {}

...

Person p = new Teacher();  // Create a Teacher
p.setColor(5);             // But access it as if it were a Person

What would it mean to "prevent inheritance"?

You could always do something like

class Teacher {
    private Person person = new Person();
}

i.e. a "has-a" relationship rather than an "is-a" relationship. But that doesn't make much sense either.

Upvotes: 0

Related Questions