I saw these two class implementations and wonder what is the diffrence between in usage of them? and when to use each of them?
class A {
B _b;
A(B b) : _b = b;
}
class B{}
and the second variation is:
class A{
B _b;
A([B? b]) : _b = b ?? B();
}
class B{}
When you don't need an instance of class B to be created via class A you can use the B constructor in class A.
But when we want to keep the B's state we can use the required parameter in the A constructor.
In the first variation, the A class does not create an instance of the B internally. Instead, it relies on an instance of the B to be injected via the constructor.
Related
I'm confusing about the rules of class instance variable override
class S0 {
num a;
S0(this.a) {
print("in S0 :$a");
}
}
class S1 extends S0 {
num a;
S1(this.a) : super(a + 1) {
print("in S1 :$a");
}
}
main() {
var b = S1(123);
print(b.a);
}
Above is my code. I expect it prints:
in S0 :124
in S1 :123
123
But the result is:
in S0 :123
in S1 :123
123
Why? thanks!
In Dart, instance variables implicitly create getter and (for non-final members) setter functions. That is, S0's interface is implicitly:
class S0 {
num get a;
set a(num value);
S0(num a);
}
From this perspective, it should be clearer that when S0 attempts to access a, it uses its getter method, which in this case is overridden by S1 and thus always returns S1's value.
The construction order is also important. Constructing an instance of the derived S1 class would execute:
The initialization list from the derived class (S1).
The initialization list from the base class (S0).
The constructor body from the base class (S0).
The constructor body from the derived class (S1).
After step 2, the object is considered sufficiently constructed for virtual dispatch to work (i.e., for overrides in the derived class to be called). (This is unlike languages such as C++ where objects are constructed purely from base class to derived and virtual dispatch in constructors is disallowed to prevent invoking methods on unconstructed objects.)
because in the constructor body access to this (and its members) is allowed. so getter and setter is generated before execute constructor.
according to instance variable
All instance variables generate an implicit getter method. Non-final instance variables also generate an implicit setter method.
and as described in Dart Programming Language Specification Chapter 10.8.1 Inheritance and Overriding
Instance variables never override each other. The getters and setters induced by
instance variables do.
so when you call this.a in class S0 it's already overrided by child class S1;
In this article about Dart Mixins there is an example at the bottom:
class S {
twice(int x) => 2 * x;
}
abstract class I {
twice(x);
}
abstract class J {
thrice(x);
}
class K extends S implements I, J {
int thrice(x) => 3* x;
}
class B {
twice(x) => x + x;
}
class A = B with K;
The article goes on to say:
Now when we define A, we get the implementation of thrice() from K’s
mixin. However, the mixin won’t provide us with an implementation of
twice(). Fortunately, B does have such an implementation, so overall A
does satisfy the requirements of I, J as well as S.
I don't undrestand why B needs to implement twice. Why does K's thrice implementation get applied to B but its inherited twice implementation doesn't?
(Notice that the linked article is out-dated and does not apply to Dart 2.)
The idea behind mixins is that "a mixin" is the difference between a class and its superclass.
For the class K, that difference is everything in its declartion after the extends clause:
implements I, J {
int thrice(x) => 3* x;
}
When you then create a new class A by applying that mixin to a different class, B, as class A = B with K; then the resulting class becomes essentially:
class A extends B implements I, J {
int thrice(x) => 3* x;
}
This class implements the interfaces I and J, and has a twice method inherited from B and a thrice method mixed in from K.
(This example is not valid Dart 2. In Dart 2, you cannot extract an interface from a class declaration with a super-class other than Object. To declare a mixin that has a notion of a super-class, you must use the mixin declaration:
mixin K on S implements I, J {
int thrice(int x) => 3* x;
}
class B implements S {
int twice(int x) => 2 * x;
}
class A = B with K;
).
Situation: Class A (Grandparent class) retains class B (Parent class) and class B(Parent class) retains class C(Child class) then If I removed class B then what would happen, Does class A and class C has a retention cycle and cause memory leaks?
Depends on how did you remove the Class B.
If I removed class B then what would happen
What do you mean by that ? If you are using ARC, you are not supposed to call release. So how did you removed the class B then?
Because Class A is holding the strong reference to class B, class B's retain count is 1. Now the only way you can bring the refrence count of Class B to 0 and let the ARC clean Class B is by setting the strong reference of Class B to nil.
So, if in your class A if you say,
self.classBReference = nil;
Then Class B's reference count becomes 0 and obviously class B gets deallocated and because Class B gets deallocated the reference count of class C becomes 0 because Class C was strongly held by class B and class B no longer exists. Hence Class C is now becomes the candidate to be removed by ARC.
Proof Of Concept :
Here is my class Declaration
class A {
var binstance : B? = B() //Declared as optional because I need to set the reference to nil later :)
deinit {
print("A deinited")
}
}
class B {
var cinstance = C()
deinit {
print("B deinited")
}
}
class C {
deinit {
print("C deinited")
}
}
Now I create instance of Class A in my VC, as a result A,B and C will all have reference count of 1.
var ainstance : A = A()
When I set the ainstance to nil here is the sequence of calls
self.ainstance.binstance = nil
O/P
B deinited
C deinited
class a {/*code*/}
class b extends a {/*more code*/}
void main() {
b c = new b();
print(c.runtimeType == a); //type == inheritedType
//or
print(c.runtimeType inherits a); //operator for inheritance
//or
print(c inherits a); //other operator for inheritance
}
Can you use type == inheriting type, type inherits other type, or instance inherits other type or type?
Is there even a way to do such thing?
Because I have not found any way yet.
Use is.
You can do c is a. Notice that new a() is a is true as well. If you really want to know if an instance is a subtype of another type, you might ask c is a && c.runtimeType != a.
I need clarity on how objects are declared and assigned a definition in F#.
What's happening in this code?
let service = {
new IService with
member this.Translate(_) = raise error }
My guess is we're creating an object that will implement some interface on the fly even though there is no actual class that's backing this object. Hence, we're removing the ceremony involved with creating an object by not having to declare a separate class to use it. In this case, we're minimizing the ceremony involved for implementing a mock object that could be used within a unit test.
Is my understanding accurate?
I tried to research my question and found the specification for F# 3.0 (Section - 6.3.8 Object Expressions)
6.3.8 Object Expressions An expression of the following form is an object expression: { new ty0 args-expropt object-members interface
ty1 object-members1 … interface tyn object-membersn } In the case
of the interface declarations, the object-members are optional and are
considered empty if absent. Each set of object-members has the form:
with member-defns endopt Lexical filtering inserts simulated $end
tokens when lightweight syntax is used. Each member of an object
expression members can use the keyword member, override, or default.
The keyword member can be used even when overriding a member or
implementing an interface.
For example:
let obj1 =
{ new System.Collections.Generic.IComparer<int> with
member x.Compare(a,b) = compare (a % 7) (b % 7) }
You can get a pretty good picture of what is happening behind the scenes if you look at the generated IL using a decompiler like ILSpy. For the example involving IComparer, it generates a hidden class, which implements the interface:
internal sealed class obj1#2 : IComparer<int> {
public obj1#2() : this() { }
int IComparer<int>.System-Collections-Generic-IComparer(int x, int y) {
int num = x % 7;
int num2 = y % 7;
if (num < num2) { return -1; }
return (num > num2) ? 1 : 0;
}
}
Inside the body of the method, it then creates a new instance:
IComparer<int> obj1 = new obj1#2();