Java接口-多重继承-Java编程思想

概述

最近把Java基础知识梳理了一下,发现了一些以前理解有偏差的地方,记录在此。

疑问

  • 一个类同时继承基类和多个接口时,该类中是否可以不实现接口中的方法?
  • 一个类同时实现多个接口,能否向上转型到各接口?
  • 一个类同时实现多个接口,接口中的方法签名是否可以保持一样?

代码解惑

package think.in.java.interfaces;//: interfaces/Adventure.java
// Multiple interfaces.

import static net.mindview.util.Print.print;

interface CanFight {
    void fight();
}

interface CanSwim {
    void swim();
}

interface CanFly {
    void fly();
}

class ActionCharacter {
    public void fight() {
        print("base class fight method");
    }
}

/**
 * 继承一个类、多个接口
 */
class Hero extends ActionCharacter
        implements CanFight, CanSwim, CanFly {
    public void swim() {
        print("sub class swim method");

    }

    public void fly() {
        print("sub class fly method");
    }

//  @Override
//  public void fight() {
//      print("sub class fight method");
//  }
}

public class Adventure {
    public static void t(CanFight x) {
        // 如果 Hero 没有重写父类的fight方法,则调用父类的fight方法
        x.fight();
    }

    public static void u(CanSwim x) {
        x.swim();
    }

    public static void v(CanFly x) {
        x.fly();
    }

    public static void w(ActionCharacter x) {
        // Hero 没有重写父类的fight方法,则调用父类的fight方法
        x.fight();
    }

    public static void main(String[] args) {
        Hero h = new Hero();
        t(h); // Treat it as a CanFight
        u(h); // Treat it as a CanSwim
        v(h); // Treat it as a CanFly
        w(h); // Treat it as an ActionCharacter
    }
} ///:~

输出:

base class fight method
sub class swim method
sub class fly method
base class fight method

一个类同时继承基类和多个接口时,该类中是否可以不实现接口中的方法?

我们发现,Hero实现了CanFight接口,CanFight接口中定义了fight()方法。但是在Hero中却并没有实现该方法。
其实这个问题也好理解,因为Hero类继承了ActionCharacter基类,而ActionCharacter基类中实现了fight()方法。父类的方法,子类自然有权限使用。
所以,在CanFight xActionCharacter x引用调用fight()方法时,自然引用到了基类的fight()方法。

一个类同时实现多个接口,能否向上转型到各接口?

这个从代码中我们可以看到,Hero子类可以作为参数传递给CanFightCanSwimCanFly等类型。所以,是可以向上转型到各接口的。

Java允许实现多个接口,而不是继承多个类。这消除了我们在组合相同基类实现时使用的两个相同成员的不确定性。
看代码:

/**
 * 第一个接口
 */
interface BaseInterface {
    void f();
}

interface IntermediateInterface1 extends BaseInterface {
    void f();
}

interface IntermediateInterface2 extends BaseInterface {
    void f();
}

/**
 * 多重继承接口
 */
interface CombinedInterface
        extends IntermediateInterface1, IntermediateInterface2 {
    void f();
}

class CombinedImpl implements CombinedInterface {
    public void f() {
        System.out.println("CombinedImpl.f()");
    }
}

/**
 * 创建一个接口,并从该接口继承两个接口,然后从后面两个接口多重继承第三个接口
 */
public class E13_Diamond {
    public static void main(String[] args) {
        new CombinedImpl().f();
    }
} /* Output:
         CombinedImpl.f()
         *///:~

一个类同时实现多个接口,接口中的方法签名是否可以保持一样?

CombinedImpl实现了CombinedInterface,而CombinedInterface又分别继承了IntermediateInterface1IntermediateInterface2接口,IntermediateInterface1IntermediateInterface2接口继承了BaseInterface接口。
而这些接口都有’f()’方法。所以是可以的。
试想一下,如果同时继承两个基类,而碰巧两个基类中有同样的方法。那么向上转型后,调用该方法,程序是不是就不知道该调用A基类的方法还是B基类的方法了呢? 不过接口是可以这么干的。

你可能感兴趣的:(Java)