Java-day13研究ノート

12日目のレビュー

ここに画像の説明を挿入

1.継承

1.1継承に関する注意

1. 子类可以继承父类的所有成员(私有的成员不能被访问)
2. 父类的构造方法可以被继承吗?不可以
		因为子类的内容肯定比父类的内容多,所以不能继承
		因为父类的构造方法名和子类的构造方法名不一致,所以不能被继承
3. 不要为了部分功能去继承

1.2継承の特徴

1. Java可以单继承
		class Father {
    
    }
		class Son extends Father {
    
    }
2. Java不可以多继承
		class Father {
    
    }
		class Mother {
    
    }
		class Son extends Father, Mother {
    
    }          //错误
		class Son extends Father extends Mother {
    
    }   //错误
3. Java可以多层继承(继承体系)
		class GrandFather {
    
    }
		class Father extends GrandFather {
    
    }
		class Son extends Father {
    
    }

1.3継承における変数間の関係

1. 如果子类和父类中变量名不同的话,直接根据不同的名字访问即可
2. 如果子类和父类中变量名相同的话,那么有如下访问规则:
		先在子类的局部范围内去找,如果找到就使用
		如果找不到就在子类的成员范围内去找,如果找到就使用
		如果找不到就在父类的成员范围内去找,如果找到就使用
		如果找不到就报错(在不考虑父类也有父类的情况),父类的局部范围不考虑(因为根本访问不到)

1.4スーパーキーワード

super可以类比this来学习

this:哪个对象调用方法this就代表哪个对象
super:代表了指向父类的地址(可以认为是父类的对象)
class Fu {
    
    

    //父类的成员位置
    String name = "曹操";

    public void test() {
    
    
        //父类的局部位置
        String name = "曹冲";
    }
}

class Zi extends Fu {
    
    

    //子类的成员位置
    String name = "曹丕";

    public void show() {
    
    
        //子类的局部位置
        String name = "曹植";
        System.out.println(name);
        System.out.println(this.name);   //如果子类有name就访问子类的,如果子类没有就访问父类的name,如果都没有就报错
        System.out.println(super.name);  //访问父类的name,如果父类没有就报错
    }

}

public class Demo {
    
    

    public static void main(String[] args) {
    
    

        //创建子类对象
        Zi z = new Zi();

        z.show();
    }
}

1.5スーパーとこれの違い

this:代表了子类的对象
super:代表了指向父类的地址(可以认为是父类的对象)

访问变量:
	this:可以访问子类的成员变量也可以访问父类的成员变量
	super:只能访问父类的成员变量
		格式:
		this.变量名;
		super.变量名;
访问方法:
	this:可以访问子类的成员方法也可以访问父类的成员方法
	super:只能访问父类的成员方法
		格式:
		this.方法名;
		super.方法名;
访问构造方法:
	格式:
		this()访问子类的无参构造方法,this(...)访问子类的带参构造方法
		super()访问父类的无参构造方法,super(...)访问父类的带参构造方法
注意:
	1. 子类的构造方法在执行之前会先执行其父类的构造方法,是因为要先将父类的内容通过构造方法初始化之后,子类才可以使用,所以子类会晚于父类进行初始化
	2. 子类的构造方法第一行默认带有super(),用来访问父类的无参构造方法
	3. this()和super()只能放在构造方法的第一行
	4. this()和super()不能同时存在
	5. this()和super()一旦显示声明了,那么会将默认的super()给覆盖掉
class Father {
    
    

    public Father() {
    
    
        System.out.println("Father的无参构造方法");
    }
    public Father(String s) {
    
    
        System.out.println("Father的带参构造方法");
    }
}

class Son extends Father {
    
    

    public Son() {
    
    
        System.out.println("Son的无参构造方法");
    }
    public Son(String s) {
    
    
        System.out.println("Son的带参构造方法");
    }
}

public class Demo3 {
    
    

    public static void main(String[] args) {
    
    

        Son s = new Son();

    }
}

1.6継承における構築方法の関係[理解]

如果父类没有无参构造方法怎么办?
	1. 子类的所有构造方法第一行都通过super(...)访问父类的带参构造方法
	2. 子类的其中一个构造方法通过super(...)访问父类的带参构造方法,而子类的其它构造方法只需要访问已经访问过父类的构造方法即可(也就是间接的完成了父类的访问)。

1.7継承におけるメンバーメソッド間の関係

如果子类和父类的方法名不一样,那么直接按照不同的方法名访问即可

如果子类和父类的方法名一样,那么有如下规则:
	1. 如果只是方法名一样,但是参数列表不一样,那么还是属于不同的方法,直接访问不同的方法即可
	2. 如果方法名一样,参数列表也一样,与返回值类型有关,那么就会执行子类的内容。以上现象被称为方法的重写。

方法重写:在继承关系中,方法名相同,参数列表也相同,与返回值类型有关。注解@Override
注意:方法一旦被重写,那么就会访问重写后的方法。

演習:
テキストメッセージ用の親クラス(携帯電話クラス)関数(メソッド使用)と、テキストメッセージの送信だけでなくゲームもプレイできるサブクラス(スマートフォンクラス)関数(メソッド使用)を記述します。継承を使用して上記のコードを完成させます。

class Phone {
    
    

    public void use(){
    
    
        System.out.println("发短信");
    }
}

class SmartPhone extends Phone {
    
    

    public void use(){
    
    
        System.out.println("发短信");
        super.use();
        System.out.println("玩游戏");
    }

}

public class Demo2 {
    
    

    public static void main(String[] args) {
    
    

        SmartPhone sp = new SmartPhone();
        sp.use();
    }
}

二、ポリモーフィズム

一つのことの多くの形。たとえば、水の状態は3つあります
。Javaのポリモーフィズム:同じものの同じ動作(メソッド)に対する異なる応答(メソッドの内容)。

2.1前提条件

1. 得有继承关系
2. 方法的重写
3. 父类引用指向子类对象
class Fu {
    
    

    public void eat(){
    
    
        System.out.println("吃饭");
    }
}

//1. 继承关系
class Zi extends Fu {
    
    

    //2. 有方法的重写
    public void eat(){
    
    
        System.out.println("吃面包");
    }
}

public class Demo {
    
    

    public static void main(String[] args) {
    
    

        Fu f = new Zi();
        f.eat();
    }
}

2.2メンバーのアクセス機能

Fu f = new Zi(); 等号的左边是父类,等号的右边是子类

成员变量:
	编译看左边的父类有没有,如果有就编译通过,如果没有直接报错
	运行看左边的父类的内容
	总结:成员变量是编译看左边运行也看左边。
成员方法:
	编译看左边的父类有没有,如果有就编译通过,如果没有直接报错
	运行看右边的子类的内容
	总结:成员方法是编译看左边运行看右边。
发现了一个问题:在多态的环境下,子类中的特有功能不能被使用,那么处理才能使用呢?
	1. 创建子类对象
	2. 向下转型

2.3上向きおよび下向きの遷移

向上转型:从小的类型转为大的类型 Fu f = new Zi();
向下转型:从大的类型转为小的类型 Zi z = (Zi)f;
class Fu {
    
    

    int i = 10;
    int j = 30;

    public void a(){
    
    
        System.out.println("Fu...a");
    }
    public void b(){
    
    
        System.out.println("Fu...b");
    }
}

class Zi extends Fu {
    
    

    int i = 20;
    int k = 50;

    public void a(){
    
    
        System.out.println("Zi...a");
    }
    public void c(){
    
    
        System.out.println("Zi...c");
    }
}

class D extends Fu {
    
    }

public class Demo {
    
    

    public static void main(String[] args) {
    
    

        Fu f = new Zi();

//        System.out.println(f.i);  //10
//        System.out.println(f.j);  //30
//        System.out.println(f.k);   //因为父类中没有此变量,所以编译报错

        f.a();
        f.b();
//        f.c();   //编译不通过

        Zi z = new Zi();
        z.c();

        //较小的数据类型 变量名 = (较小的数据类型)较大的数据类型
        Zi zz = (Zi)f;
//        D d = (D)f;   //运行报错,类型转换异常
        zz.c();
    }
}

2.4メリット

1. 提高了代码的可维护性  (通过继承保证)
2. 提高了代码的可扩展性  (通过多态保证)
/*
    动物类
 */
class Animal {
    
    

    String name;
    int age;

    public void eat(){
    
    

    }
    public void sleep(){
    
    

    }
}

/*
    猫类
 */
class Cat extends Animal {
    
    

    public Cat(String name, int age){
    
    
        this.name = name;
        this.age = age;
    }

    @Override
    public void eat() {
    
    
        System.out.println("猫吃鱼");
    }

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

/*
    狗类
 */
class Dog extends Animal {
    
    

    public Dog(String name, int age){
    
    
        this.name = name;
        this.age = age;
    }

    @Override
    public void eat() {
    
    
        System.out.println("狗吃肉");
    }

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

/*
    老虎
 */
class Tiger extends Animal {
    
    

    public Tiger(String name, int age){
    
    
        this.name = name;
        this.age = age;
    }

    @Override
    public void eat() {
    
    
        System.out.println("吃武松,但被武松反杀");
    }

    @Override
    public void sleep() {
    
    
        System.out.println("老虎躺着睡觉");
    }
}

/*
    测试类
 */
public class Demo2 {
    
    

    public static void main(String[] args) {
    
    

        Cat c = new Cat("小黑", 2);
        //初级版本:一个个调用
//        c.eat();
//        c.sleep();
        feed(c);
        Cat c2 = new Cat("小黑黑", 3);
//        c2.eat();
//        c2.sleep();
        feed(c2);
        Cat c3 = new Cat("小黑黑黑", 1);
//        c3.eat();
//        c3.sleep();
        feed(c3);
        System.out.println("-----------");
        Dog d = new Dog("小黄", 1);
        feed(d);
        Dog d2 = new Dog("小黄黄", 2);
        feed(d2);
        Dog d3 = new Dog("小黄黄黄", 3);
        feed(d3);
        System.out.println("-----------");
        Tiger t = new Tiger("小虎", 1);
        feed(t);


    }

    //终极版本
    public static void feed(Animal a){
    
      //Animal a = new Cat("小黑", 2);  //Animal a = new Tiger("小虎", 1);
        a.eat();
        a.sleep();
    }

    /*
    //升级版本:通过方法统一调用
    public static void feed(Cat c){  //传入的类型是类类型,实际上传递的是该类的对象
        c.eat();
        c.sleep();
    }

    public static void feed(Dog d) {
        d.eat();
        d.sleep();
    }

    public static void feed(Tiger t){
        t.eat();
        t.sleep();
    }
     */

}

おすすめ

転載: blog.csdn.net/ChangeNone/article/details/112622360