Let's say I have inheritance like this
Person
|
+-----+------+
| |
Student Teacher
Then I would call Person the Base.
How would I call Student?
Inherited class sounds stupid. Is there a single word for it?
Basically using Base for super class, so: PersonBase
And for it's implementations it's common to add Impl like: StudentImpl and TeacherImpl
Related
I need to make an inherited class from a base class with a selected variable.
for example,
if the base class have 3 variable name, age, marks
but inherit class must have name and marks only
how can we do it
When designing object-oriented code, subclasses should be the specializations. The situation you describe makes the base class the specialization because it has more specific requirements than the subclass.
There is a principle called the "Liskov Substitution Principle" that says all subclasses should work where the base class works - and this wouldn't be the case as calling subclass.age would fail.
Instead, the base class should have the two common properties, and there should be a subclass that represents the extended class that represents the situation where an age would be used.
Score
Name
Marks
AgedScore extends Score
Age
The names are examples here, ideally you'd name them after what they relate to in the business domain.
I have a Interface called Animal which has 5 methods (abstract). Now in my Animal kingdom we have 1000(with 1000 different overridden method ) Animals(CAT,DOG,SNAKE....etc) but creating a 1000 different class for all the animals would be hectic and even when they created managing them would be really difficult , any suggestion would be appreciated.... visual presentation is available below.
Animal(I)(5 Methods)
---------------------------------------
| | | | ----------- |
DOG CAT SNAKE LION TIGER
My main goal is to reduce the number of classes .
NOTE: every animal is overriding one or more different methods and are truly different from each other
I've a class diagram like this:
TopClass
◆ ◆
| |
SubClass1 SubClass2
◆ ◆
| |
| ChildClass2
|
ChildClass1
TopClass has SubClass1 and SubClass2.
Subclass1 has ChildClass1 and ChildClass2.
I use dependency injection on each of these classes. So when ChildClass1 needs interface X I need to pass X thru TopClass and Subclass1. When ChildClass2 needs Y I also need to pass it thru whole hierarchy. Eventually I end up with TopClass full of dependencies to interfaces it actually doesn't use. I find it smelly.
I've found an article about facade pattern which seemd promising but eventually I cannot find a way to use it in my situation.
Any other idea? And I wouldn't like to use singleton or any similar solution as I need to be able to unit tests these classes easily.
EDIT
Another option which I just found and which I'm going to test for a while is boost.DI:
http://boost-experimental.github.io/di/cpp-london-2017
http://boost-experimental.github.io/di/
If I have a class, class Animal.
And I have a class Dog and a class Cat both inheriting Animal.
Cat can call methods inside Animal. But can Cat call methods of Dog?
The answer to your question can be answered by stating it like this
Is a cat a dog?
I'll let you answer this one.
No it can not and no it should not (at least not when talking about proper OOP). If a cat really needs a dog (for whatever sick reason) you should inject the dog in the cat. If you think you need it you probably have the wrong inheritance / abstraction.
class Animal
{
public annoy();
}
class Cat extends Animal
{
private $dog;
public function __construct(Dog $dog)
{
$this->dog = $dog;
}
public function annoyDog()
{
$this->dog->annoy();
}
}
class Dog extends Animal
{
}
$dog = new Dog();
$cat = new Cat($dog);
$cat->annoyDog();
Above is an example of injection. Note that as Tony Hopkinson stated you are calling the methods on the instance of dog in this case. You could call methods on the class if they are public static, but since it is tagged OOP you really shouldn't. P.S. example is in PHP.
The methods defined in a superclass are accesible to any subclass. But "sister" classes cannot access the (private) methods of one another.
So if your classes Cat and Dog inherit from Animal, then both Cat and Dog objects can call methods from Animal, but they cannot (must not) access the methods of each other.
If I have a class, class Animal.
And I have a class Dog and a class Cat both inheriting Animal.
Cat can call methods inside Animal. But can Cat call methods of Dog?
in javascript , yes , i'll use coffeescript because it is easier to write :
class Animal
bark:-> "i'm an animal"
class Dog extends Animal
eatBone : -> "i'm eating a bone"
class Cat extends Animal
cat = new Cat
alert Dog::eatBone.call cat
Does it make sense ? probably not, but in javascript methods of a prototype are not bound to an object(unless you force it with closures). Now one could argue javascript doesnt have classes like java , but are C++ classes like Java ones ? python classes like Java ones ? who decides what's a real class or not ?
My point is the question is irrelevant outside of a language context.
Here cat and dog are two distinct classes and there is no direct relation between them.If we wish we can add few codes to link these classes. Until then the members in one cannot be accessed from the other.
If Cat doesn't inherit from Dog then no
I'm afraid that... no. Cat cannon invoke Dog methods.
Inheritance allows to "view" parents (public/protected if you are using Java) methods inside child classes, but not inside siblings classes.
Obviosly if Cat has an instance of Dog as property (I don't know why it should have...) it can call public methods of that Dog instance.
In java context [I have come across OOPs via Java]
No you cannot.
The methods that can be called by an object is determined by the reference variable.
If you use Dog/Cat reference variable it can only access methods in Dog/Cat class(including inherited and overridden ones)
If you use Animal(i.e.Parent Class) as a reference variable and have it refer to a Cat/Dog class object. You can only call the inherited/overridden methods of subclass using that reference variable.This is decided at compile time.[if the fn being called is identified by the reference variable or no]
The Dog class object is unaware of exclusive Cat class functions[other than inherited and overridden ones] so it cant call the methods.
As pointed by others, If u have a case as such u might not be looking for inheritance.
Wikipedia on the diamond problem:
"... the diamond problem is an ambiguity that arises when two classes B and C inherit from A, and class D inherits from both B and C. If a method in D calls a method defined in A (and does not override the method), and B and C have overridden that method differently, then from which class does it inherit: B, or C?"
So the diamond looks like this:
A
/ \
B C
\ /
D
My question is, what happens if there is no such class A, but again B and C declare the same method, say foo(). Isn't this the same problem? Why is it then called diamond problem?
Example:
class B {
public void foo() {...}
}
class C {
public void foo() {...}
}
class D extends B, C {
}
new D().foo();
Its not the same problem.
In the original problem, the overriden method can be called from A. In your problem this can't be the case because it does not exist.
In the diamond problem, the clash happens if class A calls the method Foo. Normally this is no problem. But in class D you can never know which instance of Foo needs to be called:
+--------+
| A |
| Foo |
| Bar |
+--------+
/ \
/ \
/ \
+--------+ +--------+
| B | | C |
| Foo | | Foo |
+--------+ +--------+
\ /
\ /
\ /
+--------+
| D |
| |
+--------+
In your problem, there is no common ancestor that can call the method. On class D there are two flavors of Foo you can chose from, but at least you know that there are two. And you can make a choice between the two.
+--------+ +--------+
| B | | C |
| Foo | | Foo |
+--------+ +--------+
\ /
\ /
\ /
+--------+
| D |
| |
+--------+
But, as always, you do not need multiple inheritance. You can use aggegration and interfaces to solve all these problems.
In the diamond problem, class D implicitly inherits the virtual method from class A. To call it, class D would call:
A::foo()
If both classes B and C override this method, then the problem comes of which actually gets called.
In your second example however, this isn't the case as class D would need to explicitly
state which was being called:
B::foo()
C::foo()
So the problems are not actually the same. In the diamond problem you aren't referencing the derived classes, but their base class, hence the ambiguity.
That's how I understand it, anyway.
Note that I'm coming from a C++ background.
Your second example is nowhere near the diamond problem because compiler has the ability to detect the available functions one level up of inheritance.
Once the compiler gets to know that you are using same-named functions in two base classes, it will throw error: member 'foo' found in multiple base classes of different types.
The diamond problem only arises from incorrect type/ontology modeling. It doesn't exist in properly-modeled systems.
The problem arises usually because developers define classes for entities based on their roles not their types. They elevate what it can do above what it actually is. The entity object carries the role not the type.
A person is a person, for example, from birth to death regardless of whether he gets married (Husband), visits mom (Son), or lands a great job (Employee). The roles for Person can be implemented with interfaces or components or mixins—fuel in the argument to prefer composition to inhertiance.
It would be reasonable to allow an entity's type to be replaced via some state machine transition. Thus, a Person could be replaced with Werewolf (full moon) or Vampire (neck bite) as the result of a state transition. The entity (some fixed GUID) remains regardless of the transition. But even this can be modeled differently—a Person with Lycanthropy and/or Vampirism. Of course, modeling to accommodate many facets can be a challenge, but it it has nothing to do with the typical limitation that classes may participate in a single inheritance chain.
An UnverifiedEmailAddress could transition to a VerifiedEmailAddress, but this is not a great example because it probably ought use a value object rather than a reference object. A better example could involve a WorkingPurchaseOrder transitioning to a SubmittedPurchaseOrder via a submit function. The function would likely return an immutable replacement (such as a Persistent Object) and be swapped into some observable state container.