I have two classes: ChildOne and ChildTwo extended from ParentClass. ChildTwo has a custom field over the inherited ones.
In some parts of the app, most of the time this ParentClass is used to display data to UI and some widgets need to know if the instance is ChildTwo to display the custom field.
However in another part of the app, I have to enhance the ParentClass, so I created another class EnhancedParentClass extends ParentClass.
This class use used in most of the widgets, but again there are some widgets that need to know the difference between the EnhancedParentClass and let's say an extended class ChildTwoEnhancedClass.
What’s the best way of solving this?
class ChildTwoEnhancedClass extends EnhancedParentClass implements ChildTwo
class ChildTwoEnhancedClass extends ChildTwo implements EnhancedParentClass
Is there a way to do this, without the need to extend the main classes “in paralel” with the “enhanced” one? Or is it something completely wrong with this implementation?
I looked over mixins, but I don’t think they fit this case, as far as I’ve seen mixins are used to share logic(mimic multiple inheritance), not necessarily share class members.
These classes are used as data immutable models.
Related
I have this question for a job interview, and i want to know why the stateful and staless widgets, use extends and why not use implements in Flutter/Dart?
Extends
extends is usually the go-to when you want to make a more specific version of a class.
When you extend a class, you inherit all properties, methods, etc.
If you want to override a method, you prefix the method with #override.
Implements
implements is when you want to make a whole new version of a class but you want to inherit the class type.
When you create a new implementation of a class, you are responsible for supplying everything necessary to make that class function.
https://dart.dev/guides/language/language-tour#implicit-interfaces
I've seen code that uses "implements", so I'm looking into "implements".
But I can't really tell the difference from extends by looking at the official docs.
Looking at the sample code in the official documentation (page above), it looks like it is just doing what it can do with extends with implements.
Then I wonder if it should use "extends".
I think I've understood about inheritance (extends) and mixins (with) so far.
The word "interface" is also mentioned in the Dart documentation, but there is a clear definition of "interface".
I can't even find where it is.
I don't have much knowledge about interfaces in other languages, so it's hard to get an image.
What exactly is the difference between inheritance and implementation?
Because of the difference, when do you use the inheritance "extends" and when do you use the implementation "implements"?
Is there somewhere in the sample that makes a clear difference?
Given class MyClass:
MyClass extends Foo is classic inheritance. MyClass is a Foo
MyClass implements Bar is declaring that the implementer conforms to the Bar interface. MyClass "looks" like a Bar
MyClass with Batz is "mixing" in the interface and implementation. MyClass "acts" like a Batz.
MyClass can implement and mixin as many interfaces as needed (some limitations apply) but can only extend from one interface.
Besides other explanations, dart does not let developers to use multiple inheritance so there can be only one extends, however there can be more than one implements.
Therefore a class can be subtype of only one class(except parents of parent class) but interfaces defines behaviour of the class which implements it and one class can have different behaviours.
A simple analogy is from animals. If we assume there is different behaviours for animals like swimming interface as ISwimmer, running interface as IRunner and flying interface as IFlyer. For example a Fish class is an Animal. Which makes it extends Animal class. Additionally a Fish has behaviour of swimming so it implements ISwimmer interface in that purpose.
If you just want to understand how they are different concept-wise then,
You extend a class. Think of it as you extended your father or your father is your base class.
You implement an interface(which is just a purely abstract class). Like Ferrari implements a car.
An interface cannot have an instance. For example - Have you seen any CAR? The answer is no, you have seen types of car i.e, Ford, Toyota which implements the CAR so the car acts as an interface which other companies or you can say, classes(Ferrari) implements.
You have to implement every feature of a car to be called a car that's why every method of an interface needs to be implemented and we say x "implements" y.
In extending you can override something and skip another , suppose your nose may look like your father but your ears do not.
Think of an interface as a skeleton or just an empty class.
I was reading an article about composition vs inheritance and the article uses the terms "domain class" and "implementation class". The author specifically says "Domain classes should use implementation classes, not inherit from them". Please explain the difference between a domain class and an implementation class.
The example of an implementation class given in the article is ArrayList. It's not part of the code describing business entities, it's just a commonly-used general purpose class.
This contrasts with the Customer class that they mention. Customer would be a class that is part of the domain, where it is describing an entity specific to the business.
The article is telling you not to extend from utility classes like this when creating domain classes.
How to Misuse Inheritance - Example 2
Creating a domain-concept class by inheriting from an implementation class is a common misuse of inheritance. For example, suppose we want to do something with a certain segment of our customers. The easy and obvious thing to do is to subclass ArrayList, call it CustomerGroup, and start coding, right?
Wrong. That would be a cross-domain inheritance relationship, and those should be avoided:
1) ArrayList is a subclass of list already, a utility collection - an implementation class.
2) CustomerGroup is another subclass - a domain class.
3) Domain classes should use implementation classes, not inherit from them.
If you need to implement a CustomerGroup class it could have an ArrayList as an instance member, like this:
public class CustomerGroup {
private List<Customer> customers = new ArrayList<>();
public List<Customer> getCustomers() {return customers;}
}
but you wouldn't make the class itself be a subclass of ArrayList.
The reason is that when you subclass something the users of your class get all the functionality of the superclass even if it isn't appropriate. You don't really need a domain class to see this in action, just go check out the source for java.util.Properties, which is badly designed, extending java.util.Hashtable. When you use a Properties object the methods from Hashtable are available to you, even though they are totally unnecessary and confusing, and using the superclass methods doesn't work or causes problems.
Among my two processes' functionality, there is a common function to merge files. I need not going to insist any of the processes to have some methods as interface does. And, also the two processes are independent. So, is it fine I just go with an Abstract class and have the implementation in that abstract class itself? Also I do not need any abstract method.
Inheritance is used when there is IS-A relation between subclass and the base class. I don't think it is the case here. You didn't specify the language, but from your profile I guess you use Java. So if you use an Abstract Class you won't be able to inherit from other, more appropriate class in the future.
Instead of inheritance you can use composition. Which means that you create a regular file merging class which has this method to merge files. And in classes where you want to have this functionality you just instantiate this new file merging class. It lets you inherit from other class in the future.
If you want to inform the world that those classes can merge files (to use polymorphism), and you use Java 8 you can create default method inside an interface and implement this interface without override this default method. But I think composition will be better in this case.
Whenever I create an abstract class I tend to create an interface to go along with it and have other code refer to the interface and not the abstract class. Usually when I don't create an interface to start with I regret it (such as having to override all implimented methods to stub the class for unit testing or later down the line new classes don't need any of the implimentation and override everything also finding themselves unable to extend any other class).
At first I tried to distinguish when to use an interface and when to use an abstract class by considering is-a vs able-to but I still would end up suffering later down the line for not making an interface to start with.
So the question is when is it a good idea to only have an abstract class and no interface at all?
When you wish to "give" some base class functionality to derived classes but when this functionality is not sufficient to instantiate a usable class, then go for abstract classes.
When you wish that some classes completely implement a set of methods (a public contract), then it is a convenient to define such contract with interfaces and enforce them onto classes by making them inherit this interface.
In short:
With abstract classes you give some common base functionality to derived classes. No further actions are necessary unless abstract class has some stubs (which have to be implemented down there).
With interfaces you require derived classes to implement a set of functions and you do not pass along any implementation.
So the question is when is it a good idea to only have an abstract class and no interface at all?
When you do not wish to enforce any public contract (a set of methods/properties defined by an interface).
Also when you do not plan to use certain coding techniques like casting object to an interface type (run-time polymorphism) or limit allowed input (some method argument will only accept object of types which implement certain interfaces).
Well, the main case it is useful to have only an abstract class without any interface is to mark a certain type. It is useful to be able to check if an object "is-a" something. These interface "mark" an objet to be of a certain type. Depending on the language you use, different design patterns apply ...
These sort of abstract classes exist in java. You can also use them in C++ with RTTI.
my2c