Looking for an explanation of an interesting Ruby observation. Consider mixing in the Comparable module as follows:
class Class0
end
class Class1
include Comparable
end
class Class2
extend Comparable
end
If we look for the methods which are in Class2 vs. Class0,
Class2.methods.each { |x| p x if not Class0.methods.include? x }
we get just :between?
But then, if we do this, to look for the difference between instances of Class1 and Class0,
a = Class0.new
b = Class1.new
b.methods.each { |x| p x if not a.methods.include? x }
we get
[:>, :>=, :<, :<=, :between?]
I would like to understand why the results are different. I would have expected the "extend" to push the same methods into the class that the "include" pushes into an instance.
Are things like ":>" not methods in the same sense as ":between?" ??
Include is for adding methods to an instance of a class and extend is for adding class methods:
http://www.railstips.org/blog/archives/2009/05/15/include-vs-extend-in-ruby/
Both :> and :between are methods.
The difference is here:
If you see Class0 methods you have :>, :>=, :<, :<= defined as class methods.
When Class2 extend Comparable it will get the between? method as class method.
In the second case you have Class0 and Class1 instances, so the a instance of Class0 doesn't have the :>, :>=, :<, :<=, :between? methods defined as instance methods. Once you include the comparable Module in Class1, it will get all this methods as instance methods from Module, so you will have all [:>, :>=, :<, :<=, :between?] methods available in the instance b.
This is why you get those results.
I found another nice explanation of include VS extend here:
http://aaronlasseigne.com/2012/01/17/explaining-include-and-extend/
Related
How can I solve the following case?
interface I
class A(i: I)
class C : I, A(this) // << --- 'this' is not defined in this context
In short, I want to pass the class instance to super class constructor.
Is it possible in Kotlin?
P.S.
All the answers are good and technically correct. But let's give a concrete example:
interface Pilot {
fun informAboutObstacle()
}
abstract class Car(private val pilot: Pilot) {
fun drive() {
while (true) {
// ....
if (haveObstacleDetected()) {
pilot.informAboutObstacle()
}
// ....
}
}
fun break() {
// stop the car
}
}
class AutopilotCar : Pilot, Car(this) { // For example, Tesla :)
override fun informAboutObstacle() {
break() // stop the car
}
}
This example don't look too contrived, and why can't I implement it with OOP-friendly language?
No, this is not possible on the JVM. this is only available after the super class has been initialized.
From
https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.10.2.4
The instance initialization method (ยง2.9.1) for class myClass sees the new uninitialized object as its this argument in local variable 0. Before that method invokes another instance initialization method of myClass or its direct superclass on this, the only operation the method can perform on this is assigning fields declared within myClass.
So the bytecode instruction aload 0 to push this on the stack is forbidden before the super-class constructor is called. That's why it cannot be passed as an argument to the super-constructor.
Kotlin was born as a JVM language and aims for maximum interoperability with Java code and a minimum overhead of its language features. While Kotlin could have chosen to orchestrate object initialization in a different way, it would create problems in mixed Java-Kotlin class hierarchies and add significant overhead.
In the good tradition of OOP languages such as Java, C# or Swift, Kotlin doesn't allow you to leak the this reference before the call to superclass initialization has completed. In your special case you're just storing the reference, but in just a slightly different case the superclass code might try to use the received object, which at that point is still uninitialized.
As a specific example of why languages don't allow this, consider a case where A is a class from a library you use and this rule is not in effect. You pass this like you do and things work fine. Later you update the library to a newer version and it happens to add something as benign as i.toString() to its constructor. It has no idea it's actually calling an overridden method on itself. Your toString() implementation observes all its invariants broken, such as uninitialized vals.
This design suffers from other problems, not just the circular initialization dependency you are struggling with now. In a nutshell, the class A expects this:
But instead you create this:
The class A has a dependency on a collaborator object of type I. It doesn't expect itself as the collaborator. This may bring about all kinds of weird bugs. For example your C.toString() may delegate to super.toString() and A.toString() (A is the super of C) may call into I.toString(), resulting in a StackOverflowError.
I can't say from your question whether A is designed for extension, which would make the C : A part correct, but you should definitely disentangle A from I.
I am just reading Dart language specification and exploring a new interesting language. As Dart language specification says: Dart has implicit interfaces. Which means every class is an interface too. So, If I want to implement some behavior of another class, implements clause is the only I need.
Also, Dart supports mixins. So that we can take implementation of methods from another class using with keyword.
So, given that if an abstract class A defines method a() like :
abstract class A {
void a();
}
and another two concrete class B defines method a() but does not implements class A like:
class B {
void a() {
print("I am class B");
}
}
and class C implements class A with Mixin B like :
class C extends Object with B implements A {
...
}
Here, I have few questions about it. If a class implements the interface and also use mixin that has method implementation with same method name; doesn't it would make cycling inheritance possible?
What will be the behaviour of class C? Does it need to implement a() or it will be implicitly implemented by mixin B?
I am just learning Dart and concepts like mixins are very unfamiliar to me. Can anyone help me understanding by answering my questions?
Mixins are a kind of limited multiple inheritance. With C with B, C inherits an implementation of void a(). Adding implements A doesn't need anything more to be done, because C already fulfills the contract it claims to fulfill by implements A, because of B.
Your link is to the Language Tour, not the specification, but the tour is definitely what you should be reading to start with.
Your example is just fine. class C extends Object with B { ... } basically adds the members of B to Object to create C. If C then satisfies the interface A it can declare support for that interface ( implements A ).
I'm facing a problem and studying the OCaml documentation did not enable me to find a satisfying solution yet.
The following snippet illustrates my problem:
class A = object (self)
(* this should not be overwrittable in subclass B, but callable
on objects of type B!
*)
method dangerous_one input =
(do dangerous stuff...)
let safe_output = safe_dangerous_one input in
(... more dangerous things done with safe_output ...)
(* This is safe, should be overwrittable and callable in subclass *)
method safe_dangerous_one input = (...)
end
class B = object(self) inherit A as super
method! safe_dangerous_one input = (* subclass behaviour ... *)
end
To sum up the snippet: class A is base class to subclass B.
It has a dangerous method that is complex and has some dark corners I don't want client code to have to deal with.
In fact, I want to prohibit subclasses from overwriting method "dangerous_one".
Instead, they should overwrite the function "safe_dangerous_one".
Furthermore, it should be possible to CALL "b#dangerous_one" where "b : B" which uses the (new) definition of the "safe_dangerous"-parts as specified in class B.
My dilemma appears to be: if I simply make method "dangerous_one" private, nothing keeps the client code in class B from overwriting it, potentially even making it public.
If I hide its implementation from the signature, it can not be overwritten anymore, but I cannot call "b#dangerous_one" anymore - the code becomes inaccessible to calls also.
Is there any way to achieve what I aim to do?
Best,
Nablezen
If I hide its implementation from the signature, it can not be overwritten anymore, but I cannot call "b#dangerous_one" anymore - the code becomes inaccessible to calls also.
You can, you just need to make it private, you can't hide public methods:
class type safe = object
method safe_dangerous_one : in_channel -> int
end
class a : safe = object (self)
method private dangerous_one input = input_binary_int input
method safe_dangerous_one input =
max 255 (self#dangerous_one input)
end
class b parameters = object(self)
inherit a parameters as super
method! safe_dangerous_one input =
super#safe_dangerous_one input + 1
end
If you want unsafe method to be accessible, but not overridable, then just re-publish it at another name (kind of NVI):
class type safe = object
method unsafe_dangerous_one : in_channel -> int
method safe_dangerous_one : in_channel -> int
end
class a : safe = object (self)
method private dangerous_one input = input_binary_int input
method unsafe_dangerous_one input = self#dangerous_one input
method safe_dangerous_one input =
max 255 (self#dangerous_one input)
end
class b = object(self)
inherit a as super
method! safe_dangerous_one input =
super#safe_dangerous_one input + 1
end
And a piece of free advice. In other languages, classes and methods are used as a tool for structuring programs, because they have no better tools. In OCaml you have first class functions, records, structures, etc. So it is better to use a proper tool for at each situation. When you design a class, you should understand, that the method by its original definition (not spoiled by C++/Java/Python/etc) is something overridable. A method is an operation that has an implementation that varies across some genera. So, if you define something as a method, and then trying hard to prevent people from overriding it, then chances are high that you're doing something wrong. If you don't want it to be overridable, then just don't define it as a method at all. In your case you should put dangerous_one operation into a let-bound function. You can bound it in the context of the class, so that you will have an access to all parameters, or you can bind it on a toplevel, the choice is yours:
class a parameters =
let dangerous_one input = input_binary_int input in
object (self)
method safe_dangerous_one input =
max 255 (dangerous_one input)
end
class b = object(self)
inherit a as super
method! safe_dangerous_one input =
super#safe_dangerous_one input + 1
end
Also, a very good source of documentation about OCaml class system is Jason Hickey's Introduction to Objective Caml. It is slightly outdated, but is still very good.
This is a general Object Oriented Programming question:
Suppose I am given a base class B:
class B {
// member functions
}
and suppose I am told to create an instance of B through the following factory method:
B createB(/* arguments */) {
b = ...
return b;
}
Now, the problem is that I need to derive from B but how am I going to initialize it as createB() does?:
class D : B {
D() {
/* need to use createB() to
initialize the base because
no equivalent constructor
exists. */
}
}
Using factory methods is in many aspects much better than just directly calling constructors. Once you've chosen using factory methods, you should stick to this approach for all the derived class - otherwise you violate the basic reason for why the factory methods have been introduced: separate the object creation from object usage.
Hence, instead of solving the issue of accessing the factory method for class B from the constructor of class D, think about creating a factory method also for the class D. Or even better: create a common factory method B createB(arguments) which decides itself what type it creates and returns.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Creating an abstract class in Objective C
In Java I like to use abstract classes to make sure that a bunch of classes has the same basic behavior, e.g.:
public abstract class A
{
// this method is seen from outside and will be called by the user
final public void doSomething()
{
// ... here do some logic which is obligatory, e.g. clean up something so that
// the inheriting classes did not have to bother with it
reallyDoIt();
}
// here the actual work is done
protected abstract void reallyDoIt();
}
Now that if class B inherits from class A, it only has to implement reallyDoIt().
How to make this in Objective C? Is it at all possible? Is it feasible in Objective C? I mean the whole paradigm seems to be different in Objective C e.g. from what I understand there is no way to forbid overriding a method (like in Java with 'final')?
Thanks!
There is no actual constraint on not overriding a method in objective c. You can use a protocol as Dan Lister suggested in his answer but this is only good to enforce your conforming class to implement a certain behavior declared in that protocol.
A solution for an abstract class in objective c could be :
interface MyClass {
}
- (id) init;
- (id) init {
[NSException raise:#"Invoked abstract method" format:#"Invoked abstract method"];
return nil;
}
This way you can prevent methods in your abstract class to be invoked (but only at run-time unlike languages like java which can detect this when on compile-time).
You'll want to use something called Protocols I think.