www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - multiple inheritance

reply "Namespace" <rswhite4 googlemail.com> writes:
How can i implement C++ behaviour like this:

class Shape : Drawable, Transformable {
class Sprite : Drawable {
class Image : Transformable {
?

One way is to declare Transformable or Drawable as interface.
But what if i have more then one class which implements 
Transformable/Drawable and i wouldn't rewrite the implementation 
of Transformable/Drawable in every class again?
Jul 08 2012
next sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 07/08/2012 07:31 PM, Namespace wrote:
 How can i implement C++ behaviour like this:

 class Shape : Drawable, Transformable {
 class Sprite : Drawable {
 class Image : Transformable {
 ?

 One way is to declare Transformable or Drawable as interface.
 But what if i have more then one class which implements
 Transformable/Drawable and i wouldn't rewrite the implementation of
 Transformable/Drawable in every class again?

Depending on what exactly your use case is, this might get you going: class Shape : Drawable { protected class MyTransformable : Transformable{ // ... // (can reference all fields of the enclosing class object) } Transformable transformable; alias transformable this; this() { transformable = new MyTransformable(); } // ... }
Jul 08 2012
parent Timon Gehr <timon.gehr gmx.ch> writes:
On 07/08/2012 07:47 PM, Namespace wrote:
 Smart idea.
 Why the inner class and not direct Transformable _t; ?

If it should be true multiple inheritance, the class must be able to override the virtual methods of each superclass and each overridden method must be given access to the fields of the class.
Jul 08 2012
prev sibling next sibling parent Wouter Verhelst <wouter grep.be> writes:
"Namespace" <rswhite4 googlemail.com> writes:

 How can i implement C++ behaviour like this:

 class Shape : Drawable, Transformable {
 class Sprite : Drawable {
 class Image : Transformable {
 ?

 One way is to declare Transformable or Drawable as interface.
 But what if i have more then one class which implements
 Transformable/Drawable and i wouldn't rewrite the implementation of
 Transformable/Drawable in every class again?

I see two options: - Make both be an Interface, but also write classes "DefaultTransformable" and "DefaultDrawable" which implement their respective Interface from which you inherit; you can then choose which of the two you reimplement and which of the two you inherit from. - Make both be an Interface, and write some templates and/or mixins with the default code that you import into child classes. That way it's just a simple "mixin(functionFoo)" per method of the interface, or the actual implementation if you don't want to "inherit". Of course, you can also do both at the same time. -- The volume of a pizza of thickness a and radius z can be described by the following formula: pi zz a
Jul 08 2012
prev sibling next sibling parent "Namespace" <rswhite4 googlemail.com> writes:
Smart idea.
Why the inner class and not direct Transformable _t; ?
Jul 08 2012
prev sibling next sibling parent "Namespace" <rswhite4 googlemail.com> writes:
I made a compromise:

[code]
import std.stdio;

interface Transformable {
public:
	void transform();
}

mixin template Transform() {
public:
	this() {
		writeln("Transform Ctor");
	}

	void transform() {
		writeln("transformiere");
	}
}

abstract class Drawable {
public:
	void draw() {
		writeln("zeichne");
	}
}

class Shape : Drawable, Transformable {
public:
	mixin Transform;

	this() {
		writeln("Shape CTor");
	}
}

void test_drawable(Drawable d) {
	d.draw();
}

void test_transformable(Transformable t) {
	t.transform();
}

void main() {
	Shape s = new Shape();

	test_drawable(s);
	test_transformable(s);
}
[/code]

Any suggestions?
Jul 08 2012
prev sibling next sibling parent "Namespace" <rswhite4 googlemail.com> writes:
And finally:

[code]
import std.stdio;

interface Transformable {
public:
	void transform();
}

mixin template _Transform() {
public:
	this() {
		writeln("Transform Ctor");
	}

	void transform() {
		writeln("transformiere");
	}
}

abstract class Transform : Transformable {
	mixin _Transform;
}

abstract class Drawable {
public:
	void draw() {
		writeln("zeichne");
	}
}

class Shape : Drawable, Transformable {
public:
	//mixin Transform;
	mixin _Transform;

	this() {
		writeln("Shape CTor");
	}
}

class Texture : Transform {
public:
	override void transform() {
		writeln("rendere texture");
	}
}

void test_drawable(Drawable d) {
	d.draw();
}

void test_transformable(Transformable t) {
	t.transform();
}

void main() {
	Shape s = new Shape();

	test_drawable(s);
	test_transformable(s);

	Texture t = new Texture();

	//test_drawable(t); // fails as expected
	test_transformable(t);
}
[/code]
Jul 08 2012
prev sibling next sibling parent "Namespace" <rswhite4 googlemail.com> writes:
I have a problem: how can i distinguish if i call a Drawable, a 
inner or a Transformable method?

I tried different ideas, but only "this.transform()" works.
Any ideas/suggestions?

Here the example code: http://dpaste.dzfl.pl/6dd9b577
Jul 09 2012
prev sibling parent "Namespace" <rswhite4 googlemail.com> writes:
The solution is simple:

mixin template _Transform() {
public:
	alias this Transformable;

	// ...
}
Jul 09 2012