簡體   English   中英

設計類層次結構 - Java中的多重繼承

[英]Designing class hierarchy - multiple inheritance in Java

我知道Java不支持多重繼承。 但是,如果我必須設計一個類系統,比如動物王國。 如何表示兩種不同動物的雜交動物? 例如,騾子(驢或馬?),獅子(獅子或老虎)。 如何繼承Lion和Tiger類來制作Liger課程? 有沒有辦法在不將Tiger和Lion作為接口的情況下做到這一點? 如果他們不能成為接口怎么辦?

在這種情況下,繼承不是正確的工具。 你看,liger 不是老虎,也不是獅子。 兩個特點,但它既不是。

假設你去動物園,籠子里寫着“老虎”。 你偷看,看到這個奇怪的巨型貓,你當然不認為是一只老虎。 這很酷 ,但不是老虎。 你也不認為它是獅子。 它也不可替代

因此,它應該組成 LionTiger並將其行為委托給正確的行為,或者完全或部分地“覆蓋”他們的行為。

更新:

現在,如果你真的想要某種多重繼承,該怎么辦,比如你想從HybridFeline衍生出Liger 看看Scala特征是否有可能。 要在Java中實現它,您需要一個接口和一個類,用於設計中您希望乘法“繼承”的每個概念。 看看這里的想法。

如果您希望單個對象可以同時識別,它們將始終需要是接口。

您通常可以將行為委托給復合類,但對於liger(它幾乎是我最喜歡的子類),您需要確定哪個動物的行為具有優先權。 liger可能是其中一個或另一個的直接后裔,或者兩者都不是。

Java只允許多個“API繼承”(接口),而不是實現。

正如你所提到的,這是不可能的。 此外,它也可能是一個糟糕的設計的跡象(因為它可能帶來歧義,即使它是可能的)。 因此,您可能必須嘗試避免它並重新考慮您的設計。

Java不支持多類繼承。 考慮“獅子”和“老虎”可能有共同的功能。 Java不想解決“功能沖突”問題:

class Lion{
    public String call(){
        return "ROAR";
    }
}
class Tiger{
    public String call(){
        return "growl";
    }
}
class Liger extends Lion, Tiger{
}

public static void main(String[] args){
    System.out.println(new Liger().call());
}

什么應該打印?

Java不支持多類繼承,因此這不起作用 - 類聲明中的“擴展Lion,Tiger”部分是非法的。 Java支持接口的消歧機制,但這並沒有擴展到類。

最好的辦法是將每個動物類轉換為一個接口,然后將代碼轉換為這些接口的實現。 Liger可以實現如下:

interface Liger extends Lion, Tiger { }
class LigerImpl implements Liger{
    private Lion mom;
    private Tiger dad;
    public LigerImpl(){
        mom = new LionImpl();
        dad = new TigerImpl();
    }
    public String call(){
        if(math.random() > 0.5){
            return mom.call();
        } else {
            return dad.call();
    }
}

這種方法需要對每個底層實現進行顯式委托; 絕對沒有任何事情“免費”發生。 不過,Java不會讓你更接近。 Java的設計幾乎歸結為“如果任何事情以任何方式模糊,不安全,未定義,或者可能導致類型或解析沖突,使程序員編寫更多代碼。”

建議你這樣做,但反思可行。 當然使用“instanceof”永遠不會工作......

public class Lion {
    public void roar() {
        System.out.println("Lion is roaring");
    }

    public void eat(String what) {
        System.out.println("Lion is eating " + what);
    }
}

public class Tiger {
    public void purr() {
        System.out.println("Tiger is purring");
    }

    public void eat(String what) {
        System.out.println("Tiger is eating " + what);
    }
}

import java.lang.reflect.Method;
import java.util.ArrayList;


public class Liger {
    public static void main(String[] args) {
        Liger liger = new Liger();
        liger.purr();
        liger.roar();
        liger.eat("food");

        //Result
        //Tiger is purring
        //Lion is roaring
        //Tiger is eating food
        //Lion is eating food
    }

    private ArrayList<Object> _extends = new ArrayList<Object>();

    public Liger() {
        _extends.add(new Tiger());
        _extends.add(new Lion());
    }

    private void invoke(String methodName, Object... args) {
        for ( Object obj : _extends ) {
            Class cls = obj.getClass();
            Method[] methods = cls.getMethods();
            for ( Method m : methods ) {
                if ( m.getName().equals(methodName) ) {
                    try {
                        m.invoke(obj, args);
                    }
                    catch ( Exception ex ) {
                        //handle me
                    }
                    continue;
                }
            }
        }
    }

    public void purr() {
        invoke("purr"); //Tiger only
    }

    public void roar() {
        invoke("roar"); // Lion only
    }

    public void eat(String what) {
        invoke("eat", what); //Both
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM