Viewed   67 times

I have an e-shop with multiple product types. And i would have thought of the following structure

Cart_Item
-- Cart_Product
-- Cart_Download

Order_Item extends Cart_Item
-- Order_Product
-- Order_Download

The problem is that i want to have Order_Product extend Order_Item and Cart_Product. This is because it needs method generic to Order_Item ( get price from Order not from product ) but also methods from Cart_Product ( shipping calculations )

I know that php doesn't support multiple inheritance, i was wandering what is the cleanest way to emulate this.

Right now i have Order_Product extend Cart_Product duplicate code from Order_Item in Order_Product an Order_Download.

 Answers

4

Either use Interfaces and implement the methods manually or via Strategies. Or use Composition instead of Inheritance, meaning you let the Order_Product have a Order_Item and a Cart_Product.

On a sidenote: You could also consider making "shipping calculations" into it's own Service class that you can pass appropriate Product instances to.

Monday, December 12, 2022
1

That will never work, because 'param' is not a property of A: it is in c, which is a property of A.

What you need to do is define the magic methods such as __set and __get, which parallel __call for properties.

Sunday, September 18, 2022
 
1

The most obvious problem is with function overriding.

Let's say have two classes A and B, both of which define a method doSomething. Now you define a third class C, which inherits from both A and B, but you don't override the doSomething method.

When the compiler seed this code...

C c = new C();
c.doSomething();

...which implementation of the method should it use? Without any further clarification, it's impossible for the compiler to resolve the ambiguity.

Besides overriding, the other big problem with multiple inheritance is the layout of the physical objects in memory.

Languages like C++ and Java and C# create a fixed address-based layout for each type of object. Something like this:

class A:
    at offset 0 ... "abc" ... 4 byte int field
    at offset 4 ... "xyz" ... 8 byte double field
    at offset 12 ... "speak" ... 4 byte function pointer

class B:
    at offset 0 ... "foo" ... 2 byte short field
    at offset 2 ... 2 bytes of alignment padding
    at offset 4 ... "bar" ... 4 byte array pointer
    at offset 8 ... "baz" ... 4 byte function pointer

When the compiler generates machine code (or bytecode), it uses those numeric offsets to access each method or field.

Multiple inheritance makes it very tricky.

If class C inherits from both A and B, the compiler has to decide whether to layout the data in AB order or in BA order.

But now imagine that you're calling methods on a B object. Is it really just a B? Or is it actually a C object being called polymorphically, through its B interface? Depending on the actual identity of the object, the physical layout will be different, and its impossible to know the offset of the function to invoke at the call-site.

The way to handle this kind of system is to ditch the fixed-layout approach, allowing each object to be queried for its layout before attempting to invoke the functions or access its fields.

So...long story short...it's a pain in the neck for compiler authors to support multiple inheritance. So when someone like Guido van Rossum designs python, or when Anders Hejlsberg designs c#, they know that supporting multiple inheritance is going to make the compiler implementations significantly more complex, and presumably they don't think the benefit is worth the cost.

Saturday, December 24, 2022
 
1

One class may implement any number of interfaces, even if those interfaces extend other interfaces as well. Multiple inheritance is not possible only with classes.

// This is not allowed
class A { void A() {} }
class B { void B() {} }
class C : A, B {}

// This is allowed
interface IA { void A(); }
interface IB { void B(); }

class A : IA, IB
{
    public void A() {}
    public void B() {}
}

The diamond problem exists with classes because there is a possibility of clashing implementations (if A and B have the same method and C extends both, which method does it take?). Interfaces, on the other hand, simply require an implementing type to have the methods that they declare.

If the exact same method is defined in two interfaces, and a class implements both interfaces, that doesn't matter. All the class needs to do is provide an implementation for the method so that code can be written to call that method. Meaning, this works:

interface IA { void Method(int x); }
interface IB { void Method(int x); }

class A : IA, IB
{
    public void Method(int x)
    {
        Console.WriteLine(x);
    }
}

Note that a class may still inherit from one other class, plus any number of interfaces:

class A : B, IA, IB {}
Tuesday, August 9, 2022
 
2

There is currently a popular style of thinking that says "favour composition over inheritance". There is too much information on Google to really list it all here, but let's just say that with the rare exception of the occasional abstract base class, I haven't used inheritance in 2-3 years.

The main idea is that any given class, rather than extending base classes that allow it to deliver required functionality, will have dependencies on other classes. In actual fact, to keep things SOLID, it'll have dependencies on interfaces that provide a contract that says they'll perform a function.

You then get to a point where your Controller class has services/components passed-in, which it delegates to in order to get specific jobs done.

Note you can go too far the other way as well. If you have a class that depends on lots of external services especially if not every public method on the class ends up using all of them, you might in fact have two classes after all. I.e. your controller is "violating" the single responsibility principle by doing more than one job. This is especially easy to do by accident with controllers in web frameworks because they kind of encourage it.

At this point, I reckon it's advisable to read up on:

  • Favour composition over inheritance.
  • Dependency Injection and Inversion of Control.
  • Inversion of Control containers (e.g. StructureMap and my personal favourite: Castle Windsor).
Sunday, November 6, 2022
 
pms1969
 
Only authorized users can answer the search term. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :