Abstract Classes & Inheritance
Java Definition + Dart Example
I’ve used abstract classes during my projects, but I figured I need to be able to describe what abstract classes and interfaces are with words, so here goes. The explanation here refers to how these concepts are used in Java.
Abstract classes cannot be used to create objects (must be inherited). It can have regular methods (those that have a body) and abstract methods, which do not have body. It cannot contain constructors, because like interfaces, it cannot be used to create objects.
To access abstract classes, you extend it.
Dart does not explicitly provide the interface keyword but all classes implicitly define an interface. More on this later, but let’s explore what interface means in other languages.
In Java, “interface is a group of related methods with empty bodies.” Notice that it said methods, and not variables. By default, interface methods are abstract and public.
To access the interface, you must implement it, unlike abstract classes which extends. Implementing an interface means that all methods defined in the interface will appear in the class. And unlike abstract classes, you can implement multiple interfaces.
When to Use Abstract Classes v. Interface
- When you want to share code among several closely related classes
- When you need fields or methods that are private, non-static, or non-final
- When unrelated classes might implement the interface
- When you want to specify a behavior of a particular data type
- When you want to inherit multiple interfaces
Implements v. Extends
Implements is used for interfaces, whereas extends is used for abstract classes. Below will be how these concepts are used in Dart.
You can use super to refer to the parent class and use its objects. It needs to be invoked in a function
You can use override to change parent class’ member, but it must match in several ways:
- Return type and argument types must be the same type/subtype
- There must be the same amount of parameters
- A generic method (<T>) cannot override a non-generic and vice versa
You can (but rarely) use covariant if you want to narrow the type of a method parameter/instance variable, but you need to make sure type error won’t occur at runtime. That means that whatever covariant you use, should be the subtype of its counterpart.
As said above, all the methods in the parent class need to exist in the subclass. Unlike Java, implements isn’t limited to interface, so think(?) abstract classes for implementation can contain variables. I would use implements when I want the subclasses to have ALL of the methods and variables in the parent class.
Here’s my example.
Abstract Class v. Class
There is one major different when it comes to inheritance between an abstract class and a normal class. When abstract classes are extended, you NEED to implement its methods.
In conclusion, I’m still confused 😕