Java学习笔记--面向对象高级(多态)

1 多态基础概念

1.1 多态理解

1.2 多态的使用场景

1.3 多态基础

1.4 练习

学生类:

属性:姓名,账号,密码

行为:work:学生的工作是学习

老师类:

属性:姓名,账号,密码

行为:work:老师的工作是教书

管理员:

属性:姓名,账号,密码

行为:work:管理员的工作是管理网站

学生管理系统:

行为:注册register

要求:能注册所有的角色

输出:姓名为张三的同学注册成功,账号zhangsan,密码123456

test1.Person

java 复制代码
package com.itstudy.test1;

public class Person {
    private String name;//姓名
    private String account;//账号
    private String password ;//密码

    //无参构造方法
    public Person() {
    }

    //有参构造方法
    public Person(String name, String account, String password) {
        this.name = name;
        this.account = account;
        this.password = password;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAccount() {
        return account;
    }

    public void setAccount(String account) {
        this.account = account; // Changed from this.account = account; to this.account = account;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public void work(){
        System.out.println("工作");
    }
}

test1.Student

java 复制代码
package com.itstudy.test1;

public class Student extends Person {

    //构造方法

    public Student() {
    }

    public Student(String name, String account, String password) {
        super(name, account, password);
    }

    //方法重写

    @Override
    public void work() {
        System.out.println("学生的工作是学习");
    }
}

test1.Teacher

java 复制代码
package com.itstudy.test1;

public class Teacher extends Person {

    //构造方法
    public Teacher() {
    }

    public Teacher(String name, String account, String password) {
        super(name, account, password);
    }

    @Override
    public void work() {
        System.out.println("老师的工作是教书");
    }
}

test1.Manager

java 复制代码
package com.itstudy.test1;

public class Manager extends Person {

    public Manager() {
    }

    public Manager(String name, String account, String password) {

        super(name, account, password);
    }

    @Override
    public void work() {
        System.out.println("管理员的工作是管理网站");
    }
}

test1.StudentManger

java 复制代码
package com.itstudy.test1;

public class StudentManger {
    //定义一个方法表示注册用户
    //参数Person:此时可以传递Person本身的对象,同时也可以传递Person所有的子类对象
    public void register(Person person) {
        //输出:姓名为张三的同学注册成功,账号zhangsan,密码123456
        System.out.println("姓名为" + person.getName() + "的账号注册成功,账号" + person.getAccount() + ",密码" + person.getPassword());

        //传递不同的对象,调用不同类里面的work方法
        person.work();
    }
}

test1.Test

java 复制代码
package com.itstudy.test1;

public class Test {
    public static void main(String[] args) {
        /*
        学生类:
                 属性:姓名,账号,密码
                 行为:work:学生的工作是学习
        老师类:
                属性:姓名,账号,密码
                行为:work:老师的工作是教书
        管理员:
                属性:姓名,账号,密码
                行为:work:管理员的工作是管理网站
        学生管理系统:
                行为:注册register
                要求:能注册所有的角色
                输出:姓名为张三的同学注册成功,账号zhangsan,密码123456
           */
        //创建学生管理系统的对象
        StudentManger sm = new StudentManger();

        //创建一个学生的对象
        Student stu = new Student("张三", "zhangsan", "123456");
        //把stu注册到学生管理系统当中
        sm.register(stu);

        //创建一个老师的对象
        Teacher tea = new Teacher("刘亚楠", "liuyanan", "123456");
        sm.register(tea);

    }

}

1.5 小结

2 多态调用成员的特点

2.1 变量调用

调用成员变量: 编译看左边,运行也看左边
编译看左边:在把java文件编译成class文件的时候 ,看父类当中有没有这个变量,如果有编译成功,如果没有编译失败
运行看左边:在代码真正运行的时候,使用父类中的变量

2.2 方法调用

调用成员方法:编译看左边,运行看右边

编译看左边:看父类当中有没有这个方法,如果没有代码报错

运行看右边:在代码真正运行的时候,运行的是子类里面的方法,如果子类没有重写父类里面的方法,使用的还是父类

2.3 多态的弊端

多态的弊端:不能调用子类的特有方法

解决多态的弊端:把对象再转回子类类型的就可以了 例: Zi z = (Zi) f;

2.4 类型转换

转类型注意点:

// 爷爷 爸爸 儿子
//创建了爸爸的对象,赋值给了爷爷类型
//在进行强制类型转换的时候,只能转到爸爸类型,不能转成儿子类型

Ye y = new Fu();//创建了爸爸的对象,赋值给了爷爷类型
Fu f1 = (Fu)y;//正确
Zi z1 =(Zi)y; //报错 //创建了爸爸的对象,赋值给了爷爷类型
//在进行强制类型转换的时候,只能转到爸爸类型,不能转成儿子类型

解决方法:面对这种容易转错的情况,可以先对其进行判断
//判断一下,y是不是父亲类型的
if (y instanceof Fu) {
Fu f1 = (Fu) y;
f1.show();
} else {
System.out.println("请确定好类型再转换");
}

2.5 练习

Test2.Ye

java 复制代码
package com.itstudy.Test2;

public class Ye {
        String name="Ye";

        public void fushow(){
            System.out.println("ye类的fushow方法被调用啦!");
        }
        public void show(){
            System.out.println("ye的show方法被调用啦!");
        }
}

Test2.Fu

java 复制代码
package com.itstudy.Test2;

public class Fu extends Ye{
    String name="Fu";

    public void fushow(){
        System.out.println("父类的fushow方法被调用啦!");
    }
    public void show(){
        System.out.println("父类的show方法被调用啦!");
    }
}

Test2.Zi

java 复制代码
package com.itstudy.Test2;

public class Zi extends Fu {
    String name="Zi";

    //子类独有的方法
    public void zishow(){
        System.out.println("子类的zishow方法被调用啦!");
    }
    //子类重写父类的方法
    @Override
    public void show(){
        System.out.println("子类重写的show方法被调用啦!");
    }
}

Test2.Test

java 复制代码
package com.itstudy.Test2;

public class Test {
    public static void main(String[] args) {
        /*
         * 变量调用:
         *         编译看左边,运行也看左边
         * 方法调用:
         *         编译看左边,运行看右边
         */

        //利用多态方式创建对象
        Fu f = new Zi();
        // 调用成员变量: 编译看左边,运行也看左边
        // 编译看左边:在把java文件编译成class文件的时候
        //            看父类当中有没有这个变量,如果有编译成功,如果没有编译失败
        // 运行看左边:在代码真正运行的时候,使用父类中的变量
        System.out.println(f.name);
        // System.out.println(f.age);


        //调用成员方法:编译看左边,运行看右边
        //  编译看左边:看父类当中有没有这个方法,如果没有代码报错
        //  运行看右边:在代码真正运行的时候,运行的是子类里面的方法
        //             如果子类没有重写父类里面的方法,使用的还是父类
        f.show();

        //问题一:为什么调用fushow方法程序没有报错?
        //    因为fushow方法在父类当中存在,编译不会报错(遵循编译看左边的原则)
        //问题二:程序运行的结果是什么?
        //    程序运行的结果是:父类的fushow方法被调用啦!(子类没有这个方法,使用的还是父类的)
        f.fushow();

        //  f.zishow(); 报错,因为zishow方法在子类当中不存在,编译会报错(遵循编译看左边的原则)

        //多态的弊端:不能调用子类的特有方法
        //解决多态的弊端:
        //     把对象再转回子类类型的就可以了
        Zi z = (Zi) f;
        z.zishow();

        //注意点:
        // 爷爷 爸爸 儿子
        //创建了爸爸的对象,赋值给了爷爷类型
        //在进行强制类型转换的时候,只能转到爸爸类型,不能转成儿子类型

        Ye y = new Fu();
        /*
        Fu f1 = (Fu)y; //创建了爸爸的对象,赋值给了爷爷类型
        Zi z1 =(Zi)y;  //报错  //创建了爸爸的对象,赋值给了爷爷类型
        //在进行强制类型转换的时候,只能转到爸爸类型,不能转成儿子类型
        */

        //面对这种容易转错的情况,可以先对其进行判断
        //判断一下,y是不是父亲类型的
        if (y instanceof Fu) {
            Fu f1 = (Fu) y;
            f1.show();
        } else {
            System.out.println("请确定好类型再转换");
        }
    }
}

输出结果:

Fu

子类重写的show方法被调用啦!

父类的fushow方法被调用啦!

子类的zishow方法被调用啦!

父类的show方法被调用啦!

2.6 小结

3 多态的综合练习

test3.Person

java 复制代码
package com.itstudy.test3;

public class Person {
    private String name;
    private int age;//年龄
    private String gender;//性别

    public Person() {
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public void useTransport(Transport transport){
        transport.move();
       // transport.honk();//多态中不能直接调用子类特有方法
       if(transport instanceof Car){
           Car c = (Car)transport;
           c.honk();
       }
       else if(transport instanceof Bicycle){
           Bicycle bic = (Bicycle)transport;
           bic.ringBell();
       }else{
           System.out.println("没有这个类型");
       }
    }
}

test3.Transport

java 复制代码
package com.itstudy.test3;

public class Transport {
    private String brand;
    private double speed;

    public Transport() {
    }

    public Transport(String brand, double speed) {
        this.brand = brand;
        this.speed = speed;
    }

    public String getBrand() {
        return brand;
    }

    public void setBrand(String brand) {
        this.brand = brand;
    }

    public double getSpeed() {
        return speed;
    }

    public void setSpeed(double speed) {
        this.speed = speed;
    }

    public void move() {
        System.out.println(brand+"的交通工具正在以"+speed+"的速度移动");
    }

}

test3.Bicycle

java 复制代码
package com.itstudy.test3;

public class Bicycle extends Transport {
    public Bicycle() {
    }

    public Bicycle(String brand, double speed) {
        super(brand, speed);
    }

    @Override
    public void move() {
        System.out.println(getBrand()+"的交通工具正在以"+getSpeed()+"的速度移动");
    }

    public void ringBell() {
        System.out.println("自行车正在响铃");
    }
}

test3.Car

java 复制代码
package com.itstudy.test3;

public class Car extends Transport {
    public Car() {
    }

    public Car(String brand, double speed) {
        super(brand, speed);
    }
    @Override
    public void move() {
        System.out.println(getBrand()+"的交通工具正在以"+getSpeed()+"的速度移动");
    }

    public void honk() {
        System.out.println("汽车正在鸣笛");
    }
}

test3.Test

java 复制代码
package com.itstudy.test3;

public class Test {
    public static void main(String[] args) {
          /*
    练习 多态的综合练习
        自行车:Bicycle
        属性:品牌,行驶速度
        行为:移动 move,响铃 ringBell()
        汽车:Car
        属性:品牌,行驶速度
        行为:移动 move,鸣笛 honk()
        人:Person
        属性:名字,年龄,性别
        行为:行驶交通工具(能使用所有交通工具)
        交通工具 Transport
    */

        Person per = new Person("张三", 18, "男");
        //ai没有自动生成代码时:Alt+P 强制ai生成代码    或者 写注释,提示ai生成

        //输出打印对象的所有信息
        System.out.println(per.getName() + " " + per.getAge() + " " + per.getGender());

        Bicycle bic = new Bicycle("凤凰牌自行车", 25);
        per.useTransport(bic);
        Car c = new Car("玛莎拉蒂汽车", 60);
        per.useTransport(c);
    }
}

输出结果:

张三 18 男

凤凰牌自行车的交通工具正在以25.0的速度移动

自行车正在响铃

玛莎拉蒂汽车的交通工具正在以60.0的速度移动

汽车正在鸣笛

4 总结

5 课堂作业

5.1 学生使用图形的方法

5.2 动物饲养

相关推荐
AA陈超2 小时前
003 XiYou 西游 — P0 阶段实施计划
c++·笔记·学习·ue5
其实防守也摸鱼2 小时前
运维--安全与数据库
网络·数据库·学习·安全·安全威胁分析·数据库架构·软件安全
pop_xiaoli2 小时前
【iOS】YYModel源码学习
学习·ios·objective-c·cocoa
嵌入式-老费3 小时前
esp32开发与应用(利用loopback学习can)
学习
沪上企服通3 小时前
上海地区代账服务供给侧的五种架构形态:从 pipeline SLA 到领域深度的选型笔记
笔记·架构
xianrenli384 小时前
DS5900作业之“氛围(Vibe)”背后的伦理
学习·ai编程·msai
iuu_star4 小时前
Python大模型智能学习平台——设计与实现(AI教学系统)
大数据·人工智能·python·学习
库玛西4 小时前
深入剖析 Linux 线程机制与分页式存储管理
linux·服务器·c++·笔记
奋发向前wcx4 小时前
y1,y2总复习笔记2 2026.7.15
java·笔记·算法