第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定

Java中的抽象類與接口(2)

標(biāo)簽:
Java

Java里面除了抽象类和接口的区别这种头疼并且不容易搞明白的问题还有很多很重要的问题并且有些也很好玩所以抽象类和接口到底有啥区别可以留到今后的工作中慢慢体会因为随着阅历的增长对对面向对象的理解和能熟练使用继承结构以后这将不再是个问题

有一个比较有意思的问题比这个有趣既然AbstractList实现了List接口那为什么ArrayList继承了AbstractList之后还要再实现List接口呢通过运行代码就能明白

public class Test1 {
    public interface List {
        void get();
    }

    public static abstract class AbstractList implements List {
        public abstract void get();
    }

    public static class Class1 extends AbstractList implements List {
        @Override
        public void get() {
            System.out.println("Class1.get()");
        }
    }

    public static class Class2 extends AbstractList {
        @Override
        public void get() {
            System.out.println("Class2.get()");
        }
    }

    private static <T> T invoke(final T obj) {
        final InvocationHandler handler = new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                return method.invoke(obj, args);
            }
        };
        return (T) Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), handler);
    }

    public static void main(String[] args) {
        // 这个可以调用成功
        List list1 = invoke(new Class1());
        list1.get();
        // 这个会抛异常,这是因为Class1隐式实现List,而Class2显示实现List
        List list2 = invoke(new Class2());
        list2.get();
    }
}


可以看到Class1继承了AbstractList之后又显式实现了List接口Class2仅仅只是继承了AbstractList然后通过反射再重新声明Class1Class2回会发现Class2抛异常了——这就是为什么需要显式再实现一次List的原因——如果想要获取已实现接口的子类的动态代理那这个子类就必须显式实现接口

说直白点就是没有直接实现接口的类用反射的时候就要小心了

 

另一个比较有趣而且面试的时候可能会问的比较多的问题会是下面关于类的多重继承问题

假设有如下条件

1、接口A和接口B拥有相同的方法

2、接口B继承接口A,C是独立接口

3、D有和A、B相同的方法

用代码来解释就是

public interface A {
   default void hello() {
      System.out.println("Hello from A");
   }
}
 
public interface B extends A {
   default void hello() {
      System.out.println("Hello from B");
   }
}
 
public interface C {
   default void hello() {
      System.out.println("Hello from C");
   }
}
 
public class D {
   public void hello() {
      System.out.println("Hello from D");
   }
}



那么问题来了

1、类E同时实现A、B,会调用AB哪个父类接口的方法呢

public class E implements A, B {
   public static void main(String[] args) {
      new E().hello();
   }
}



2、类E继承D,同时实现A、B,会调用ABD哪个父类的方法呢

public class E extends D implements A, B {
   public static void main(String[] args) {
      new E().hello();
   }
}



3、E同时实现ABC时会调用ABC哪个父类接口的方法呢

public class E implements A, B, C {
   @Override
   public void hello() {
      C.super.hello();
   }

   public static void main(String[] args) {
      new E().hello();
   }
}


4、E同时实现ABC且继承自D时会调用ABCD哪个父类接口的方法呢

public class E extends D implements A, B, C {
   public static void main(String[] args) {
      new E().hello();
   }
}


其实这就是Java中设计的继承原则分别如下

1、第一个问题遵循子类优先原则:当接口之间有继承关系时,子接口的优先级最高

2、第二个问题遵循类优先原则:继承自类的方法优先级最高(E实现D的方法)

3、第三个问题遵循指定关系原则:当接口之间无继承关系时,编译器会强制指定方法的具体实现(例如接口B和接口C无继承关系那么此时需要在B和C之间选一个)

4、第四个问题可参照第二个问题的原则解释类优先原则

 

Java里面的多重继承也就这么点东西了

 


點(diǎn)擊查看更多內(nèi)容
TA 點(diǎn)贊

若覺(jué)得本文不錯(cuò),就分享一下吧!

評(píng)論

作者其他優(yōu)質(zhì)文章

正在加載中
  • 推薦
  • 評(píng)論
  • 收藏
  • 共同學(xué)習(xí),寫(xiě)下你的評(píng)論
感謝您的支持,我會(huì)繼續(xù)努力的~
掃碼打賞,你說(shuō)多少就多少
贊賞金額會(huì)直接到老師賬戶
支付方式
打開(kāi)微信掃一掃,即可進(jìn)行掃碼打賞哦
今天注冊(cè)有機(jī)會(huì)得

100積分直接送

付費(fèi)專欄免費(fèi)學(xué)

大額優(yōu)惠券免費(fèi)領(lǐng)

立即參與 放棄機(jī)會(huì)
微信客服

購(gòu)課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)

舉報(bào)

0/150
提交
取消