首頁  >  文章  >  Java  >  如何掌握Java抽象類別與介面?

如何掌握Java抽象類別與介面?

WBOY
WBOY轉載
2023-05-08 08:16:071099瀏覽

    abstract

    abstract介紹:可以用來修飾:類別(抽象類別)、方法(抽象方法)

    abstract修飾類:

    ①此類不能實例化(也就是不能創建這個類別的物件)

    ②雖然自己不能實例化,但是子類別會呼叫父類別的建構器,所以抽象類別中一定有建構器

    abstract修飾方法

    ①抽象方法只有方法的宣告沒有方法體,所在的類別一定是抽象類別。因為如果類別不是抽象的,那麼這個類別就可以造對象,可以造對象就可以呼叫。反之抽象類別中可以沒有抽象方法。

    ② 若子類別重寫了子類別重寫了父類別所有的抽象方法才能實例化,如果沒有全部重寫,那麼子類別也是抽象類,也需要用abstract修飾。

    ③abstract不能用來修飾私有方法、靜態方法、final關鍵字修飾的方法、final關鍵字修飾的類別。

    final明確不能繼承,但abstract需要子類別繼承所以不能用,因為如果兩個方法都是static,不認為兩個方法是重寫或覆蓋,所以abstract用來修飾靜態方法,就無法重寫。

    抽象的應用

    模板方法設計模式。在軟體開發中實作一個演算法時,整體步驟很固定、通用,這些步驟在父類別中寫好,某些易變的和不確定的部分可以抽象化給子類別實作。

    抽象類別的匿名子類別物件

    public static void main(String[] args){
        //匿名对象
        eat(new son());
        //非匿名类的非匿名对象
        son John=new son();
        eat(John);
        //匿名子类对象
        father f=new father(){//抽象类造对象必须要重写方法,了解看得懂就ok了。
            @Override
            public void work() {
            }
            @Override
            public void info(father i) {
            }
        };
    }
    //普通方法
    public static void eat(father f){
        System.out.println("吃饭");
    }
    //父类
    public abstract static class father{
        String name;
        int age;
        public abstract void work();//抽象方法不能有方法体
        public abstract void info(father i);
    }
    //子类
    public class son extends father{//继承
        String name;
        int age;
        @Override
        public void work(){
            System.out.println("上学");
        }
        @Override
        public void info(father i) {
            System.out.println("name:"+i.name+" age:"+i.age);
        }
    }
    //接口的匿名对象
    非匿名的对象可以被多次调用,匿名的对象只能使用一次
    Computer com=new Computer();//创建了接口的非匿名实现类(子类)的非匿名对象,类和对象都是有名的
    Flash flash = new Flash();
    //2.创建了接口的非匿名实现类的匿名对象,对象匿名了
    com.transferData(new Printer());
    //3创建了接口的匿名实现类的非匿名对象,就是类是匿名的,就不知道是接口中的哪个实现类,所以 需要重写方法进行说明
    USB  phone = new USB{
        public void start(){
            ...
        }
    };
    //4.创建了接口的匿名实现类的匿名对象
    com.transferData(new USB(){
        public void start(){
            ...
        }  
        });

    final關鍵字

    final修飾類別:此類不能被其他類別所繼承,例如:String、System、StringBuffer

    final修飾方法:此方法不能再被重寫,例如:Object類別中的getClass()

    static final用來修飾屬性:全域常數

    ##final修飾變量:此時的變數稱為是常數

    final修飾屬​​性:可以考慮賦值的位置:明確初始化,程式碼區塊中初始化、建構器中初始化

    final修飾局部變數:尤其是用final修飾形參時,表明此形參是一個常量,當調用此方法時,給常量形參賦實參,一旦賦值就只能在方法體內使用此形參,但不能重新賦值

    介面

    介面使用Interface來定義,和類別是並列關係

    介面的定義以及介面中的成員:

    介面相關規則

    1.介面中所有方法都是抽象的。

    2.即使沒有明確的將介面中的成員用public標示,也是public存取類型的

    3.介面中變數預設用public static final標示,所以介面中定義的變數就是全域靜態常數。

    4.可以定義一個新接口,用extends去繼承一個已有的接口

    5.可以定義一個類,用implements去實現一個接口中所有方法。

    6.可以定義一個抽象類,用implements去實作一個介面中部分方法。

    介面的特性

    1.介面不可以被實例化

    2.實作類別必須實作介面的所有方法

    3.實作類別可以實作多個介面

    4.介面中的變數都是靜態常數

    如果類別覆寫了介面中所有的抽象方法,則可以創造實例;如果類別沒有覆寫介面中所有的抽象方法,則該類別仍為抽象類別。 Java類別可以實作多個介面——彌補了單繼承性的缺陷

    class AA extends BB implements CC,DD,EE

    介面和介面之間可以繼承,而且可以多繼承。介面的使用體現了多態性。介面是一種規範,面向介面程式設計。

    抽象類別和介面的異同

    相同點:不能實例化,都可以包含抽象方法

    不同點:

    1. 把抽象類和介面(java7、java8)的定義、內部結構解釋說明

    2. 類別:單一繼承性,介面:多繼承性。

    抽象類別與介面的練習

     abstract class Door {
        //开门
        public abstract void openDoor();
        //关门
        public abstract void closeDoor();
    }
     interface Lock {
        public static final int num = 200;
        //开锁
        public abstract void openLock();
        //上锁
        public abstract void closeLock();
    }
    class LockDoor extends Door implements Lock {
        public void openDoor() {
            System.out.println("开门");
        }
        public void closeDoor() {
            System.out.println("关门");
        }
        public void openLock() {
            System.out.println("开锁");
        }
        public void closeLock() {
            System.out.println("上锁");
        }
      }
    public class TestLockDoor {
        public static void main(String[] args) {
            LockDoor lockDoor = new LockDoor();
            lockDoor.openLock();
            lockDoor.openDoor();
            lockDoor.closeDoor();
            lockDoor.closeLock();
        }
    }

    介面的應用程式

    兩種設計模式

    - 代理模式

    代理程式設計就是為其他物件提供一個代理程式以控制對這個物件的存取

    應用程式場景:安全代理程式、遠端代理程式、延遲載入

    分類:靜態代理程式、動態代理程式

    # - 工廠模式

    實作創建者和呼叫者的分離

    interface A{
        int x=0;
    }
    class B{
        int x=1;
    }
    class C extends B implements A{
        public void pX(){
            System.out.println(x);
        }
        public static void main(String[] args){
            new C().pX();
        }
    }
    //问题:编译期不知道是要输出哪个x
    System.out.println(super.x);//这个调用的是父类中的
    System.out.println(A.x);//这个调用的是接口中的

    java8中介面新特性

    JDK8:除了全域常數和抽象方法,還可以定義靜態方法和預設方法(default關鍵字修飾)

    public interface CompareA{  
      public static void method1(){
      //静态方法        
      System.out.println("CompareA:北京");   
       }   
        public default void method2(){
        //默认方法        
        System.out.println("CompareA:上海");   
         }
      }

    介面中定義的靜態方法只能透過介面來調用,介面.方法。

    透過實作類別的對象,可以呼叫介面中的預設方法,物件.方法。

    如果實作類別重寫了介面中的預設方法,呼叫時仍然呼叫的是重寫以後的方法

    如果子類別(或實作類別)繼承的父類別和實作的介面中宣告了同名同參數的方法,子類別在沒有重寫此方法的情況下呼叫的是父類別中的方法——類別優先原則

    如果实现类实现了多个接口,而这个多个接口中定义了同名同参数的默认方法,在实现类没有重写方法的情况下会报”接口冲突“错误,此时需要重写。

    如何在子类(或者实现类)调用父类、接口中被重写的方法? 接口.super.方法。

    内部类

    需要关注的问题:如何实例化成员内部类的对象:外部类Person,静态内部类Brain,非静态内部类Lungs,静态成员内部类:new 外部类.内部类()

    Person.Brain brain=new Person.Brain();

    非静态成员内部类:先造对象,对象.new 内部类()

    Person p=new Person();
    p.Lungs lungs=p.new Lungs();

    如何在成员内部类中区分调用外部类的结构

    形参直接调,所在类的用this.结构,外部类的用外部类.this.结构

    成员内部类和局部内部类在编译以后都会生成字节码文件

    成员内部类:外部类.内部类名.class

    局部内部类:外部类.数字 内部类名.class

    在局部内部类的方法中,如果调用局部内部类所在的方法中的局部变量,该局部变量必须用final关键字修饰(JAVA8之后可以不写出来,但仍然还是final的)

    public void Person(){
        int num=10;
        class AA{//局部内部类
            public void show(){//局部内部类的方法
                num=20;//试图修改会报错
                System.out.println(num);//调用局部内部类所在的方法中的局部变量
            }
        }
    }

    开发中局部内部类的使用

    常用的局部内部类:

    //方式一
    public Comparable getCompareble(){
        class MyComparable implements Comparable{//局部内部类
    
            public int compareTo(Object o){
                return 0;
            }
        }
        return new MyComparable();
    }
    //方式二
    public Comparable getCompareble(){
        return new Comparable(){
    
            public int CompareTo(Object o){
                return 0;
            }
        };
    }

    Java允许将一个类A声明在另一个类B中,A为内部类,B为外部类

    内部类的分类:成员内部类、局部内部类(方法内,代码块内,构造器内)

    成员内部类

    作为外部类的成员:可以调用外部类的结构,可以被static修饰

    作为一个类:可以定义属性、方法、构造器,可以用final、abstract修饰,可以被继承

    this.name//内部类的属性

    Person.this.name//外部类的属性

    以上是如何掌握Java抽象類別與介面?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

    陳述:
    本文轉載於:yisu.com。如有侵權,請聯絡admin@php.cn刪除