What is the difference between:
class A {}
class B with A{}
and
mixin A{}
class B with A{}
?
In Dart, a class can only extend one other class. But it can implement or mixin as many as you want.
The thing is, when you extend a class, you inherit all its attributes, methods and it's constructors. When you implement a class, if you are adding only methods/attributes that you don't already have, you can simply continue your code. If you are implementing an abstract method, you'll need to actually implement it. Now, mixins are like extended classes, the classes that mix them, are their child as well as with extend and implements, but it has no constructor.
The actual idea for mixins is that you can add functionalities to any class, and they don't have to extend another class. That's why they usually do simple stuff only.
Related
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.
Hey I have being looking a lot and watching a lot of videos about inheritance.
There is just this concept of abstract classes which means that it cant be implemented.
I get that you cant use a abstract class on a gameobject but what is the force of using a abstract class?
Also can abstract method only be implemented in a abstract class, and why cant you implement the method in a abstract class but only override it?
I also read something about a abstract method taking a component<T> and I havent found out what the purpase of that was hope some of you clever minds can help a confused programmer :D
Abstract classes are used to model a shared "master class" which will never be used itself but derived classes of it will use that data/functions.
For example say your inheritance is
Animal
Bird Mammal Reptile
In your game, you will only ever use a Bird/Mammal/Reptile since those are concrete models of animals, But they all will share at least some common amount of code. Health, Hunger, and may provide some abstract functions such as Move() which will be implemented on a per subclass level.
From an engineering standpoint, this let's you do fancy things such as create an array/vector of type Animal which can contain birds, mammals, and reptiles.
So say we have a vector of type Animal with 1 of each subclass.
We can then do
foreach (Animal a in animals)
a.Move(100)
Birds/Mammals/Reptiles all move differently, but because we have that abstract function with no implementation at the base level, our code can guarantee that at some point in the inheritance tree it is implemented.
Other popular examples are an abstract class of Item and the abstract function item.Use(); Item could be a Potion, a Scroll, an apple (class Food). It doesn't matter because they all share that same base level interface.
I think reading Microsoft's article on Abstract Classes and Methods would be extremely helpful. You utilize abstract classes by providing base functionality to a class and inheriting from it.
You're also confusing some wording with implement and override: you implement an abstract method by overriding it.
Component<T> means that the class Component with the type parameter as something you define. This is defined in C# as Generics. You utilize these with base Unity3D classes like Component<GameObject> or GetComponent<GameObject>.
It seems to me that I can make just about anything using object, trait, abstract class and in rare occasions, case class. Most of this is in the form object extends trait. So, I'm wondering, when should I, if ever, use a plain, standard class?
This is not a right place to ask this question
Looks like you are new Scala
Class is a specification for something(some entity) you want to model . It contains behavior and state
There is only one way to declare so called regular class using keyword class
Both trait and abstract class are used for inheritance.
trait is used for inheritance (generally to put common behavior in there). trait is akin to interface in Java. multiple inheritance possible with traits but not abstract class.
A class can extends one class or abstract class but can mixin any number of traits. Traits can have behavior and state.
case class is a nothing but a class but compiler produces some boilerplate code for us to make things easy and look good.
object is used when you want to declare some class but you want to have single instance of the class in the JVM (remember singleton pattern).
If an object performs stateful computations on its members i.e. its members are declared with vars;
Or, even if its member are only declared with vals but those vals store mutable data structures which can be edited in place, then it should be an ordinary (mutable) class akin to a Java mutable object.
The idiomatic way of using Case classes in Scala is as immutable types i.e. all the constructor arguments are vals. We could use vars but then we lose the advantages of case classes like equality comparisons will break over time.
Some advise from Programming in Scala by Odersky et al on deciding between using traits, abstract classes and concrete classes:
If the behavior will not be reused, then make it a concrete class. It is not reusable behavior after all.
If it might be reused in multiple, unrelated classes, make it a trait.
Only traits can be mixed into different parts of the class hierarchy.
If you want to inherit from it in Java code, use an abstract class.
Since traits with code do not have a close Java analog, it tends to be
awkward to inherit from a trait in a Java class. Inheriting from a
Scala class, meanwhile, is exactly like inheriting from a Java class.
As one exception, a Scala trait with only abstract members translates
directly to a Java interface, so you should feel free to define such
traits even if you expect Java code to inherit from it. See Chapter 29
for more information on working with Java and Scala together.
If you plan to distribute it in compiled form, and you expect outside
groups to write classes inheriting from it, you might lean towards
using an abstract class. The issue is that when a trait gains or loses
a member, any classes that inherit from it must be recompiled, even if
they have not changed. If outside clients will only call into the
behavior, instead of inheriting from it, then using a trait is fine.
If efficiency is very important, lean towards using a class. Most Java
runtimes make a virtual method invocation of a class member a faster
operation than an interface method invocation. Traits get compiled to
interfaces and therefore may pay a slight performance overhead.
However, you should make this choice only if you know that the trait
in question constitutes a performance bottleneck and have evidence
that using a class instead actually solves the problem.
If you still do not know, after considering the above, then start by
making it as a trait. You can always
change it later, and in general using a trait keeps more options open.
I'm puzzled to choose a trait or class when writing scala code.
At first, I have a controller which with several traits:
class MyController extends Controller
with TransactionSupport
with JsonConverterSupport
with LoggerSupport
In these traits, I defined some methods and fields which can be used in MyController directly.
But my friend says: when you extends or with a trait, it should be a that trait.
Look at the MyController, it is a Controller, but it isn't a TransactionSupport, not a JsonConverterSupport, not a LoggerSupport, so it should not with them.
So the code becomes:
class MyController(tranSupport: TransactionSupport,
jsonConverter: JsonConverterSupport,
loggerSupport: LoggerSupport) extends Controller
But I don't feel good about this code, it just seems strange.
I see traits used heavily in scala code, when should I use it or use classes to inject?
I'll refer you to Interfaces should be Adjectives. Though some traits may play the part of a class (and, therefore, be nouns and respect the "is-a" relationship), when used as mixins they'll tend to play the part of interfaces.
As an "adjective", the trait will add a qualifying property to whatever they are extending. For example, they may be Comparable or Serializable.
It can be a bit hard to find an adjective to fit -- what adjective would you use for LoggerSupport? -- so don't feel overly constrained by that. Just be aware that it is completely wrong to thing of traits as necessarily an "is-a" relationship.
I would try to avoid using traits to replace "has-a" relationships, though.
My opinion is that it doesn't have to be it. Mixing-in is a different concept than inheritance. Even though syntactically it is the same, it doesn't mean the same. Typical use case for mixing-in is logging just like you wrote. It doesn't mean that if your service class mixes-in a Logging trait that it is a logger. It's just a yet another way how to compose functionality into working objects.
Odersky proposes that if you are not sure and you can, use traits because they are more flexible. You can change trait to class in the future if you need.
Sometime when I feel that mixing-in trait doesn't look good, I use module pattern like this:
trait JsonConverterModule {
protected def jsonConverter: JsonConverter
protected trait JsonConverter {
def convert(in: Json): Json
}
}
class MyController extends Controller with JsonConverterModule {
private doSmth = jsonConverter.convert(...)
}
MyController in this case looks more like a Controller, and all Json-related stuff is hidden from MyController 'client'
Your first example with traits is the "cake pattern" and your second example is "constructor injection". Both are perfectly valid ways to do dependency injection in Scala. The cake pattern is powerful, you can inject type members, the different traits can easily talk to each other (we don't have to create separate objects and pass them to each other object, often requiring setter injection rather than simple constructor injection), etc. However, the type has to be realized at compile-time, and a separate class must be realized for every combination of traits. Constructor injection lets you build your object at run-time and scales better for a large number of combinations.
I have a clue about Object Oriented Programming:
I need to have a parent class HandlerException which needs to define the sign of three methods (MethodA, MethodB, MethodC).
Then, I have a child class BusinessHandler which inherits from HandlerException and defines ONLY the MethodA of its parent class.
Then, I have a child class DataHandler which inherits from HandlerException and defines ONLY MethodC of its parent class.
Then, I have a class named CustomerDAO which inherits from DataHandler and consumes the MethodC written on its parent class. (consumes it like: DataHandler.MethodC).
As you can see, its a typical object oriented programming problem; I need to have some static methods (MethodC) to access it directly without any instance of the class. The parent class HandlerException could be abstract? and its 3 methods (A, B and C) could be ???? (that's my question, how is the RIGHT way to write this parent class: abstract with abstract members, or virtual, or maybe an interface?)
I hope you got the idea of my question and that I made myself clear. Thanks in advance.
I forgot: I'm using C#, and to mention: MethodB would be implemented on the next release of the app.
Depends on the language you are using, but it sounds like the HandlerException class would be abstract and all three methods would be virtual.
If the HandlerException class has absolutely no implementation whatsoever (only defines those three methods) then it would probably make sense to make it an interface rather than an abstract class.
Also, where is MethodB implemented? If it isn't implemented by any of those classes, then all the classes would need to be abstract.