10.オブジェクト指向(抽象クラス、インターフェース)

抽象クラス

レビュー

package org.westos.demo;

/**
 * @author lwj
 * @date 2020/4/20 16:46
 */
public class MyDemo {
    public static void main(String[] args) {
        Panda panda = new Panda();
        //抽象类AbstractAnimal初始化
        //Panda构造方法执行了
        System.out.println(panda.num);
        //20
    }
}

abstract class AbstractAnimal {

    /** 抽象类不能直接实例化,但是抽象类存在构造方法,目的是子类在创建对象时需要初始化父类(抽象类)的数据 */
    public AbstractAnimal() {
        System.out.println("抽象类AbstractAnimal初始化");
        //1
    }

    public void sleep() {
        System.out.println("睡觉");
    }

    /**
     * 抽象方法eat
     */
    protected abstract void eat();
}

class Panda extends AbstractAnimal {
    {
        num = 20;
    }
    int num;

    public Panda() {
        System.out.println("Panda构造方法执行了");
        //2
    }

    @Override
    protected void eat() {
        System.out.println("大熊猫吃竹子");
    }
}

class Cat extends AbstractAnimal {

    public Cat() {
        System.out.println("Cat构造方法执行了");
    }

    @Override
    protected void eat() {
        System.out.println("猫咪吃小鱼干");
    }
}

抽象クラスメンバーの機能

  • メンバー変数:変数または定数のいずれか
  • コンストラクター:存在、子クラスがオブジェクトを作成するときに親クラスのデータを初期化するために使用されます
  • メンバーメソッド:抽象または非抽象のいずれかです。
    • 抽象メソッド:サブクラスに抽象メソッドを実装させる
    • 非抽象メソッド:サブクラスは親クラスのメソッドをオーバーライドできるかどうか
package org.westos.demo;

/**
 * @author lwj
 * @date 2020/4/20 17:14
 */
public class MyDemo2 {
    public static void main(String[] args) {
        Student student = new Student(2);
        System.out.println(student.nation);
        //中国
        student.show();
        //我是父类
        //子类重写父类的show()方法
        student.abstractMethod();
        //我是子类
    }
}

abstract class AbstractPerson {
    public int id = 1;

    /** final类型变量在定义后,1、在定义声明时初始化,2、在构造代码块中初始化,3、在构造方法中初始化 */
    public final String nation;

    {
        nation = "中国";
    }

    public AbstractPerson(int id) {
        this.id = id;
    }
    /** 抽象方法 */
    public abstract void abstractMethod();

    public void show() {
        System.out.println("我是父类");
    }
}

class Student extends AbstractPerson {

    /*由于父类的构造方法只有一个有参构造,而子类默认无参构造,调用父类的无参构造失败,所以报错,
      解决:子类生成一个有参构造,并且显式调用父类有参构造 */

    public Student(int id) {
        super(id);
    }

    @Override
    public void abstractMethod() {
        System.out.println("我是子类");
    }

    @Override
    public void show() {
        super.show();
        System.out.println("子类重写父类的show()方法");
    }
}

抽象クラスの質問にインタビューする

1.クラスに抽象メソッドがない場合、それを抽象クラスとして定義できますか?もしそうなら、ポイントは何ですか?

はい、そのようなオブジェクトは作成できません。

2.抽象化と共存できるキーワードはどれですか。

  1. 抽象変更メソッド、サブクラスはこのメソッドをオーバーライドする必要があります。プライベート変更メソッド、サブクラスは継承できません。オーバーライドできないため、競合します。

  2. 抽象クラスを表す抽象変更クラス、サブクラスは抽象クラスを継承し、最終と競合します(変更クラス、変更クラスは継承できません);

  3. 抽象クラス内の抽象メソッド、抽象クラスを継承するサブクラスを表す抽象装飾メソッドは、抽象クラスに抽象メソッドを実装する必要があり、finalと競合します(装飾メソッド、変更されたメソッドはサブクラスによってオーバーライドできません)。

  4. 抽象変更メソッド、抽象メソッドを表す、メソッド本体なし、静的変更メソッドは静的メソッドを表し、メソッド本体あり、書き換えに参加しない、共存できない、無意味。

インターフェース

インターフェースの特徴

  • インターフェイスは、キーワードインターフェイス、インターフェイスインターフェイス名{}で表されます
  • クラスはキーワードimplementsを使用してインターフェースを実装し、クラスクラスはインターフェース名{}を実装します
  • インターフェイスをインスタンス化することはできません。多態的な方法でインスタンス化できます
  • インターフェースのサブクラス
    • 抽象クラス、抽象クラスclass nameはインターフェース名{}を実装します
    • 具象クラス。インターフェースのすべての抽象メソッドをオーバーライドするには、クラスクラス名がインターフェース名{}を実装します
package org.westos.demo2;

/**
 * @author lwj
 * @date 2020/4/20 17:33
 */
public class MyDemo {
}

interface IExpandMethod {
    /**
     * 打电话
     */
    public abstract void call();
}

abstract class AbstractAnimal implements IExpandMethod {

}

class Animal implements IExpandMethod {

    @Override
    public void call() {
        System.out.println("具体类必须实现接口中所有方法");
    }
}

インターフェースのメンバー特性

  • メンバー変数:定数のみであり、デフォルトの修飾子はpublic staticです:public static final
  • コンストラクター:インターフェースにコンストラクターはありません
  • メンバーメソッド:抽象メソッドのみにすることができます。デフォルトの修飾子:public abstract

クラスとクラス、クラスとインターフェース、インターフェースとインターフェース

  • クラスとクラス:継承関係、単一継承のみ、多重継承。
  • クラスとインターフェース:実装関係。1つまたは複数を実装できます。複数のインターフェースを,分離し、クラスを継承しながら複数のインターフェースを実装できます
  • インターフェースとインターフェース:継承関係は、単一継承または多重継承のいずれかです。
//类与类:extends,单继承
//类与接口:implements,单实现,多实现
public final class Integer extends Number implements Comparable<Integer> {}
public class ArrayList<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable{}
//接口与接口:extends,单继承,多继承
public interface List<E> extends Collection<E> {}
public interface SortedMap<K,V> extends Map<K,V> {}

抽象クラスとインターフェースの違い

メンバー間の違い:

  • 抽象クラス:
    • メンバー変数:変数、定数
    • コンストラクタ:コンストラクタがあります
    • メンバーメソッド:抽象にすることも、非抽象にすることもできます
  • インターフェース:
    • メンバー変数:定数のみ
    • コンストラクタ:コンストラクタはありません
    • メンバーメソッド:抽象のみ

関係の違い:

  • クラスとクラス
    • 相続
  • クラスとインターフェース
    • 実現、単一実現、複数実現
  • インターフェースとインターフェース
    • 継承、単一継承、多重継承

設計コンセプトの違い:

  • 抽象クラス
    • 継承されるのは「is a」の関係です。抽象クラスは継承されたクラスの共通機能を定義します
  • インターフェース
    • 実現されるものは「ライクa」関係を反映し、継承システムの拡張機能はインターフェースで定義されます

注:JDK 1.8以降デフォルト装飾されたメソッドがインターフェース提供されます。これにより、関数の特定の実装を提供でき、サブクラスはそれを継承できます。

package org.westos.demo3;

/**
 * @author lwj
 * @date 2020/4/20 20:09
 */
public interface IExpandMethod {
    int NUMBER = 10;

    /**
     * 1、jdk1.7 公共静态常量和public abstract抽象方法
     * 钻火圈
     */
    void fire();

    /**
     * 2、jdk1.8 增加default关键字修饰方法,可以存在方法体,默认权限修饰符为public
     * 展示
     */
    default void show() {
        System.out.println("展示");
    }

    /**
     * 3、jdk1.8 增加static静态方法,默认权限修饰符为public
     * 测试
     */
    static void test() {
        System.out.println("静态方法");
    }
}

class ExpandMethodImpl implements IExpandMethod {

    @Override
    public void fire() {
        System.out.println("钻火圈");
    }
}

class MyDemo {
    public static void main(String[] args) {
        IExpandMethod test = new ExpandMethodImpl();
        test.fire();
        //钻火圈
        test.show();
        //展示
        System.out.println(IExpandMethod.NUMBER);
        //10
        IExpandMethod.test();
        //静态方法
    }
}

抽象クラスとインターフェースの演習

抽象クラス

package org.westos.demo3;

/**
 * @author lwj
 * @date 2020/4/20 20:36
 */
public abstract class Animal {
    public String name;
    public int age;

    /**
     * 吃饭
     */
    public abstract void eat();

    /**
     * 睡觉
     */
    public abstract void sleep();
}

実装クラス

package org.westos.demo3;

/**
 * @author lwj
 * @date 2020/4/20 20:38
 */
public class Cat extends Animal{
    @Override
    public void eat() {
        System.out.println("猫吃鱼");
    }

    @Override
    public void sleep() {
        System.out.println("猫睡觉");
    }
}

拡張機能

package org.westos.demo3;

/**
 * 扩展功能
 * @author lwj
 * @date 2020/4/20 20:42
 */
public interface IHighJump {
    /**
     * 动物跳高
     */
    void highJump();
}

ガーフィールド

package org.westos.demo3;

/**
 * 加菲猫
 * @author lwj
 * @date 2020/4/20 20:40
 */
public class Garfield extends Cat implements IHighJump{
    @Override
    public void eat() {
        System.out.println("加菲猫吃鱼排");
    }

    @Override
    public void sleep() {
        System.out.println("加菲猫睡在沙发上");
    }

    @Override
    public void highJump() {
        System.out.println("加菲猫学会了跳高");
    }
}

ジャコウネコ

package org.westos.demo3;

/**
 * 狸花猫
 * @author lwj
 * @date 2020/4/20 20:44
 */
public class CivetCat extends Cat {
    @Override
    public void eat() {
        System.out.println("狸花猫吃鱼翅");
    }

    @Override
    public void sleep() {
        System.out.println("狸花猫睡在摇篮里");
    }
    
    public void catchMouse() {
        System.out.println("狸花猫抓老鼠");
    }
}

試験方法

package org.westos.demo3;

/**
 * @author lwj
 * @date 2020/4/20 20:46
 */
public class MyTest {
    public static void main(String[] args) {
        Garfield garfield = new Garfield();
        Cat cat = garfield;
        cat.name = "波斯猫";
        cat.age = 2;
        cat.eat();
        cat.sleep();
        IHighJump jump = garfield;
        jump.highJump();
        System.out.println("===============");
        CivetCat civetCat = new CivetCat();
        cat = civetCat;
        cat.name = "狸花猫";
        cat.age = 3;
        cat.eat();
        cat.sleep();
        CivetCat civetCat1 = (CivetCat) cat;
        //执行CivetCat的特有方法,需要向下转型
        civetCat1.catchMouse();
    }
}

おすすめ

転載: www.cnblogs.com/shawnyue-08/p/12740529.html