day02-面向对象高级

今日内容

  • 多态
  • 抽象类
  • 接口

今日目标

  • 能够知道多态的前提
  • 能够理解多态的好处和弊端
  • 能够理解多态中的转型
  • 能够知道抽象类的特点
  • 能够知道抽象类的成员特点
  • 能够知道接口的特点
  • 能够知道接口的成员特点
  • 能够理解抽象类和接口的区别

1.多态

1.1 多态概述

【什么是多态】

  • 指的是同一个对象,在不同时刻表现出来的多种形态

    • 我们可以说猫是猫: cat = new ();
    • 我们也可以说猫是动物:动物 animal = new ();
    • 这里猫在不同的时刻表现出来了多种形态,这就是多态

【前提】

  • 有继承/实现关系
  • 有方法重写
  • 有父类引用指向子类对象

【代码】

public class Animal {public void eat() {System.out.println("动物吃东西");}}
public class Cat extends Animal {@Overridepublic void eat() {System.out.println("猫吃鱼");}}
/*多态的前提有继承/实现关系有方法重写有父类引用指向子类对象*/
public class Test {public static void main(String[] args) {//有父类引用指向子类对象Animal a = new Cat();}
}

1.2 多态中成员访问特点

【特点】

  • Fu f = new Zi();

    • 成员变量: f.成员变量

      • 编译看左边: 成员变量在父类中是否存在

        • 存在,编译通过
        • 不存在,编译错误
      • 执行看左边: 访问Fu类的成员变量
    • 成员方法: f.成员方法()
      • 编译看左边:成员方法在父类中是否存在

        • 存在: 编译通过
        • 不存在:编译失败
      • 执行看右边: 调用的子类的方法(最主要的特点)

【代码】

public class Fu {public int age = 50;public void eat(){System.out.println("父类中的eat方法");}
}
public class Zi extends Fu{public int age = 20;public int height = 180;@Overridepublic void eat() {System.out.println("子类中的eat方法");}public void show(){System.out.println("子类中的show方法");}
}
public class Test {/*练习: 多态的前提,多态前提下成员的访问特点成员变量: 编译看左边,运行看左边(访问父类的成员变量)成员方法: 编译看左边,运行看右边(调用子类的成员方法)*/public static void main(String[] args) {Fu f = new Zi();System.out.println(f.age);
//        f.heightf.eat();
//        f.show();}
}

1.3 多态的好处和弊端

【好处】

  • 提高了程序的扩展性

    • 父类的引用记录的是哪一个子类的对象,调用方法是,执行就是那个子类的方法
//        Animal a = new Cat();
//        Animal a = new Dog();Animal a = new Pig();a.eat();

【代码】

public class Animal {public void eat(){System.out.println("动物吃东西");}
}
public class Horse extends Animal{@Overridepublic void eat() {System.out.println("马吃草");}
}
public class Test {/*多态的好处 : 提高程序的扩展性调用方法时,传递不同的对象就能实现不同的效果*/public static void main(String[] args) {//        Animal a = new Cat();
//        Animal a = new Dog();
//        Animal a = new Pig();
//        a.eat();show(new Horse());}// 定义一个方法看看每种动物都吃什么public static void show(Animal a){// 数据类型 名字// Animal a 引用数据类型的变量// Animal a = new Horse(); // 父类引用指向子类的对象a.eat();}}

【弊端】

  • 不能使用子类的特有功能

    • 多态的使用更多就是为了看不同子类的表现,调用的重写的方法
    • 就想调用子类特有的方法???
Animal a = new Cat();
a.eat()  // 重写方法 可以正常执行
a.work() // 编译错误 没有办法调用子类特有的方法

1.4 多态中的转型

【向上转型】

  • 父类引用指向子类对象
Animal a = new Cat();

【向下转型】

  • 父类引用转为子类对象

    • 解决访问子类特有方法的弊端
Cat c = (Cat) a;

【ClassCastException】

  • 向下转型是,有可能会出现类型转换异常

  • 原因: 变量类型 和 记录的地址无关的

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9Ga5OC9O-1661926258214)(assets/image-20220827095746038.png)]

【instanceof】

  • 变量/地址值 instanceof 类名
  • 示例: a1 instanceof Dog a1 是不是狗
    • 如果是 返回结果就是true
    • 不是 返回结果就是false
  • 作用: 避免类型转换异常
if (a1 instanceof Dog){// 向下转型Dog d = (Dog) a1;
}

1.5 案例:猫和狗(多态版)

【步骤】

① 定义动物类(Animal)

  • 成员变量:姓名,年龄
  • 构造方法:无参,带参
  • 成员方法:get/set,吃(){}

② 定义猫类(Cat),继承动物类,重写吃的方法

  • 构造方法:无参,带参
  • 成员方法:吃(){}
  • 成员方法:工作(){} 抓老鼠

③ 定义狗类(Dog),继承动物类,重写吃的方法

  • 构造方法:无参,带参
  • 成员方法:吃(){}

④ 定义测试类(AnimalDemo),写代码测试

【代码】

2.抽象类

2.1 抽象类概述

【抽象方法】

Java中,一个没有方法体的方法为抽象方法

示例: public abstract void show();

【抽象类】

一个类中如果有抽象方法,该类必须是抽象类

【为什么要定义抽象方法】

  • 在多态的前提下: Fu f = new Zi();
  • 调用方法时: f.show(); 执行的一定是子类的方法
  • 父类中的方法永远执行不到的

【代码】

2.2 抽象类特点

【特点】

  • 抽象类抽象方法必须使用abstract修饰

    • public abstract class 类名{}
    • public abstract void eat();
  • 抽象类中不一定有抽象方法,有抽象方法的类一定是抽象类
  • 抽象类不能实例化
    • 抽象类如何实例化呢?使用多态的方式 实例化子类
  • 抽象类的子类
    • 要么重写抽象类中的所有抽象方法
    • 要么是抽象类

【代码】

/*抽象类*/
public abstract class Animal {//抽象方法public abstract void eat();public void sleep() {System.out.println("睡觉");}}
public class Cat extends Animal {@Overridepublic void eat() {System.out.println("猫吃鱼");}
}
public abstract class Dog extends Animal {}
/*测试类*/
public class AnimalDemo {public static void main(String[] args) {//        Animal a = new Animal();Animal a = new Cat();a.eat();a.sleep();}
}

2.3 抽象类的成员特点

  • literals: 字面量(常量) : “”,‘’,10,12.5,true,false null
  • constant: 常量: 不能被修改的变量称值为常量
    • final修饰的变量

【成员变量】

  • 可以是变量
  • 也可以是常量(final修饰的)

【成员方法】

  • 可以有抽象方法:限定子类必须完成某些动作
  • 也可以有非抽象方法:提高代码复用性,非私有成员方法,子类可以直接使用的

【构造方法】

  • 有构造方法,但是不能实例化
  • 那么,构造方法的作用是什么呢?用于子类访问父类数据的初始化(给成员变量赋值)

【代码】

/*抽象类*/
public abstract class Animal {private int age = 20;private final String name = "动物";public Animal() {}public Animal(int age) {this.age = age;}public void show() {age = 40;System.out.println(age);
//        name = "老虎";System.out.println(name);}public abstract void eat();}
public class Cat extends Animal {@Overridepublic void eat() {System.out.println("猫吃鱼");}
}
/*测试类*/
public class AnimalDemo {public static void main(String[] args) {Animal a = new Cat();a.eat();a.show();}
}

2.4 案例:猫和狗(抽象类版)

需求:请采用抽象类的思想实现猫和狗的案例,并在测试类中进行测试

看完需求后,我们先简单的说一下思路:

思路:

① 定义动物类(Animal)

  • 成员变量:姓名,年龄
  • 构造方法:无参,带参
  • 成员方法:get/set,吃();

② 定义猫类(Cat),继承动物类,重写吃的方法

  • 构造方法:无参,带参
  • 成员方法:吃(){…}
  • 成员方法:工作(){} 抓老鼠

③ 定义狗类(Dog),继承动物类,重写吃的方法

  • 构造方法:无参,带参
  • 成员方法:吃(){…}

④ 定义测试类(AnimalDemo),写代码测试

3.接口

3.1 接口概述

【生活中的接口】

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZketYNNS-1661926258215)(imgs/1640785171549.png)]

这是我们房间中比较常见的五孔插线面板,我们再来一个五孔插线面板。

大家认真看一下啊,这是两种不同类型的插线面板,对插线面板有了解的同学,应该能够看出来。

左边这个是公牛的,右边这个是西门子的。

为什么不同厂商生成的插线面板装到你家里,你都可以使用呢?

原因很简单,因为这些面板是这些厂商遵循同样的规范生产的。

所以说,接口啊,就是一种公共的规范,只要符合规范,大家都可以使用。

这是我们生活当中的,其实与计算机相关的接口也随处可见:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tS3ZqOVy-1661926258216)(imgs/1640785329296.png)]

这是笔记本,有两个USB插口,可以用来连接外接设备。

我们在使用笔记本的时候,有些操作我们发现使用键盘不方便,这里呢,我们就可以提供一个鼠标,插入到这个USB插口里面就可以使用了。

再比如说,笔记本上的键盘用起来我感觉不是很方便,而且我担心给他敲坏了,怎么本?我们就可以提供一个外置的键盘,插入到这个USB插口里面也就可以使用了。

再比如说,我电脑上有一些学习资料,我要给你。如果有网络,我们可以通过一些网络软件发送给你,如果没有网络,怎么办呢?这个时候,我们就可以通过这样的一个小工具:U盘来拷贝资料。

插入到这个USB插口里面也就可以使用了。

看到这里,我们思考一下,这些产品是由不同的厂商生产的,但是它们却都可以通过这个USB插口接到这个电脑上,这是为什么呢?

原因很简单,因为它们参照的是同样的USB插口规范来实现的。无论是尺寸,厚度等都是有标准参数的。所以,虽然它们是不同的厂商生产的,但是却可以通过这个USB插口来使用。

【什么是接口】

  • 接口就是一种公共的规范标准,只有符合规范标准(具备这个功能),大家都可以通用
  • Java中的接口更多的体现在对行为(方法)的抽象

3.2 接口特点

【特点】

  • 接口用关键字interface修饰

    • public interface 接口名 {}
  • 类实现接口用implements表示
    • public class 类名 implements 接口名 {}
  • 接口不能实例化
    • 接口如何实例化呢?参照多态的方式,通过实现类对象实例化,这叫接口多态
    • 多态的形式:具体类多态,抽象类多态,接口多态
    • 多态的前提:有继承或者实现关系;有方法重写;有父(类/接口)引用指向(子/实现)类对象
  • 接口的实现类
    • 要么重写接口中的所有抽象方法
    • 要么是抽象类

【代码】

/*定义了一个接口*/
public interface Inter {public abstract void show();
}
public class InterImpl implements Inter {@Overridepublic void show() {System.out.println("show...");}
}
public abstract class InterImpl2 implements Inter{}
/*测试类*/
public class InterDemo {public static void main(String[] args) {//        Inter i = new Inter();Inter i = new InterImpl();i.show();}
}

3.3 接口的成员特点

【成员变量】

  • 只能是常量
  • 默认修饰符:public static final

【构造方法】

  • 没有,因为接口主要是扩展功能的,而没有具体存在
  • 一个类如果没有父类,默认继承自Object类

【成员方法】

  • 只能是抽象方法
  • 默认修饰符:public abstract
  • 关于接口中的方法,JDK8和JDK9中有一些新特性,后面再讲解
public interface Inter {public int num = 10;public final int num2 = 20;
//    public static final int num3 = 30;int num3 = 30;//    public Inter() {}//    public void show() {}public abstract void method();void show();}
//public class InterImpl implements Inter {public class InterImpl extends Object implements Inter {public InterImpl() {super();}@Overridepublic void method() {System.out.println("method");}@Overridepublic void show() {System.out.println("show");}
}
/*测试类*/
public class InterfaceDemo {public static void main(String[] args) {Inter i = new InterImpl();
//        i.num = 20;System.out.println(i.num);
//        i.num2 = 40;System.out.println(i.num2);System.out.println(Inter.num);}
}

3.4 类和接口的关系

  • 类和类的关系

    • 继承关系,只能单继承,但是可以多层继承
  • 类和接口的关系
    • 实现关系,可以单实现,也可以多实现,还可以在继承一个类的同时实现多个接口
  • 接口和接口的关系
    • 继承关系,可以单继承,也可以多继承,也可以多层继承
public interface Inter1 {}
public interface Inter2 {}
public interface Inter3 extends Inter1,Inter2 {}
public class InterImpl extends Object implements Inter1,Inter2,Inter3 {}

3.5 抽象类和接口的区别

来,继续啊,下面我们来学习抽象类和接口的区别。

我们一起来说一下:

  • 成员区别

    • 抽象类 变量,常量;有构造方法;有抽象方法,也有非抽象方法
    • 接口 常量;没有构造方法;抽象方法
  • 关系区别
    • 类与类 继承,单继承
    • 类与接口 实现,可以单实现,也可以多实现
    • 接口与接口 继承,单继承,多继承
  • 设计理念区别
    • 抽象类 对类抽象,包括属性、行为???
    • 接口 主要是行为抽象???

3.6 案例:木门和电动报警门

需求:请采用面向对象的思想实现木门和电动报警门的案例,并在测试类中进行测试

看完需求后,我们先简单的分析一下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pgm3bO2z-1661926258216)(imgs/1641276207662.png)]

分析:

①木门

  • 成员变量:宽,高,品牌
  • 成员方法:开门,关门

②电动报警门:

  • 成员变量:宽,高,品牌
  • 成员方法:开门,关门,报警

图解

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kyebABhr-1661926258217)(assets/image-20220827123638168.png)]

思路:

①定义报警 (Alarm)接口

  • 成员方法:报警

②定义门 (Door)抽象类

  • 成员变量:宽,高,品牌
  • 构造方法:无参,带参
  • 成员方法:get/set方法,开门,关门

③定义木门类(WoodDoor),继承门类

  • 构造方法:无参,带参
  • 成员方法:开门,关门

④定义电动报警门类(ElectricAlarmDoor),继承门类,实现报警接口

  • 构造方法:无参,带参
  • 成员方法:开门,关门,报警

⑤定义测试类(DoorDemo),创建对象进行测试

知道了实现思路后,下面我们一起到IDEA中去实现一下:

/*报警接口*/
public interface Alarm {void alarm();
}
/*抽象门类*/
public abstract class Door {//宽private double width;//高private double height;//品牌private String brand;public Door() {}public Door(double width, double height, String brand) {this.width = width;this.height = height;this.brand = brand;}public double getWidth() {return width;}public void setWidth(double width) {this.width = width;}public double getHeight() {return height;}public void setHeight(double height) {this.height = height;}public String getBrand() {return brand;}public void setBrand(String brand) {this.brand = brand;}//开门public abstract void open();//关门public abstract void close();
}
/*木门*/
public class WoodDoor extends Door {public WoodDoor() {}public WoodDoor(double width, double height, String brand) {super(width, height, brand);}@Overridepublic void open() {System.out.println("手动开门");}@Overridepublic void close() {System.out.println("手动关门");}
}
/*电动报警门*/
public class ElectricAlarmDoor extends Door implements Alarm {public ElectricAlarmDoor() {}public ElectricAlarmDoor(double width, double height, String brand) {super(width, height, brand);}@Overridepublic void open() {System.out.println("自动开门");}@Overridepublic void close() {System.out.println("自动关门");}@Overridepublic void alarm() {System.out.println("具有报警功能");}
}
/*测试类*/
public class DoorDemo {public static void main(String[] args) {//木门WoodDoor wd = new WoodDoor();wd.open();wd.close();
//        wd.alarm();System.out.println("--------");//电动报警门ElectricAlarmDoor ed = new ElectricAlarmDoor();ed.open();ed.close();ed.alarm();System.out.println("--------");//多态用法Door d = new WoodDoor();d.open();d.close();System.out.println("--------");d = new ElectricAlarmDoor();d.open();d.close();
//        d.alarm();System.out.println("--------");Alarm a = new ElectricAlarmDoor();
//        a.open();
//        a.close();a.alarm();}
}

3.7 接口新增的方法

【接口组成】

  • 常量

    • public static final
  • 抽象方法
    • public abstract
  • 默认方法(Java 8)
  • 静态方法(Java 8)
  • 私有方法(Java 9)

【默认方法】

  • 接口中默认方法的定义格式

    • 格式:public default 返回值类型 方法名(参数列表) { }
    • 范例:public default void show1() { }
  • 接口中默认方法的注意事项

    • public可以省略,default不能省略

【静态方法】

  • 接口中静态方法的定义格式

    • 格式:public static 返回值类型 方法名(参数列表) { }
    • 范例:public static void show2() { }
  • 接口中静态方法的注意事项

    • 静态方法只能通过接口名调用,不能通过实现类名或者对象名调用
    • public可以省略,static不能省略

【私有方法】

  • 接口中私有方法的定义格式

    • 格式1:private 返回值类型 方法名(参数列表) { }
    • 范例1:private void show3() { }
    • 格式2:private static 返回值类型 方法名(参数列表) { }
    • 范例2:private static void show4() { }
  • 接口中私有方法的注意事项

    • 默认方法可以调用私有的静态方法和非静态方法
    • 静态方法只能调用私有的静态方法

【代码】

public interface Inter {//    public default void show1() {//        System.out.println("默认方法被调用");
//    }default void show1() {System.out.println("默认方法被调用");show3();show4();}//    public static void show2() {//        System.out.println("静态方法被调用");
//    }static void show2() {System.out.println("静态方法被调用");
//        show3();show4();}private void show3() {System.out.println("私有方法");}private static void show4() {System.out.println("静态私有方法");}}
public class InterImpl implements Inter {}
/*测试类*/
public class InterDemo {public static void main(String[] args) {Inter i = new InterImpl();i.show1();
//        i.show2();
//        InterImpl.show2();Inter.show2();}
}

面向对象高级,学习记录2相关推荐

  1. Python|装饰器|执行时间|递归|动态属性|静态方法和类|继承和多态|isinstance类型判断|溢出|“魔法”方法|语言基础50课:学习记录(6)-函数的高级应用、面向对象编程、进阶及应用

    文章目录 系列目录 原项目地址: 第16课:函数的高级应用 装饰器(记录执行时间的例子) 递归调用 简单的总结 第17课:面向对象编程入门 类和对象 定义类 创建和使用对象 初始化方法 打印对象 面向 ...

  2. Python学习笔记:面向对象高级编程(完)

    前言 最近在学习深度学习,已经跑出了几个模型,但Pyhton的基础不够扎实,因此,开始补习Python了,大家都推荐廖雪峰的课程,因此,开始了学习,但光学有没有用,还要和大家讨论一下,因此,写下这些帖 ...

  3. Python学习笔记:面向对象高级编程(中下)

    前言 最近在学习深度学习,已经跑出了几个模型,但Pyhton的基础不够扎实,因此,开始补习Python了,大家都推荐廖雪峰的课程,因此,开始了学习,但光学有没有用,还要和大家讨论一下,因此,写下这些帖 ...

  4. Python学习笔记:面向对象高级编程(中上)

    前言 最近在学习深度学习,已经跑出了几个模型,但Pyhton的基础不够扎实,因此,开始补习Python了,大家都推荐廖雪峰的课程,因此,开始了学习,但光学有没有用,还要和大家讨论一下,因此,写下这些帖 ...

  5. Python学习笔记:面向对象高级编程(上)

    前言 最近在学习深度学习,已经跑出了几个模型,但Pyhton的基础不够扎实,因此,开始补习Python了,大家都推荐廖雪峰的课程,因此,开始了学习,但光学有没有用,还要和大家讨论一下,因此,写下这些帖 ...

  6. rtt学习记录、面向对象oopc等分享

    懒得在搬过来了, 我把笔记链接发过来 rt-thread有道笔记 内容简介: 1.rtt学习记录,包括内核源码.env.scons.组件等学习记录. 2.rtt面向对象思想oopc,以串口为例详细分析 ...

  7. Python学习之面向对象高级编程

    Python学习目录 1. 在Mac下使用Python3 2. Python学习之数据类型 3. Python学习之函数 4. Python学习之高级特性 5. Python学习之函数式编程 6. P ...

  8. 【Makefile由浅入深完全学习记录6】Makefile中变量的高级主题上

    抓住基础,学习更多技术,迎接挑战,加qq:1126137994 微信:liu1126137994 一起学习更多技术~ 上一篇文章学习了makefile中的预定义变量的使用,今天来继续学习makefil ...

  9. python getattrribute_Python学习——面向对象高级之反射

    本篇是python的面向对象高级篇,主要描述反射.内置属性与方法.元类:为下一篇的ORM框架做好准备.废话不多说,咱就从反射开始吧. 反射 第一次听说反射这个术语,还是在自学Java的时候看到,知道了 ...

最新文章

  1. mysql connections参数_MySQL性能优化之max_connections配置参数浅析
  2. 【网页前端设计Front end】JavaScript教程.上(看不懂你来打我)
  3. 朋友圈产品文档_企业微信上线朋友圈等新功能,超250万企业接入企业微信
  4. c语言设计指导实训,C语言程序设计实训指导
  5. Percona XtraBackup User Manual 阅读笔记
  6. java冒泡法程序,Java基础之冒泡法的实现
  7. 勒索病毒c语言源代码,勒索病毒原理解析
  8. linux docker运行exe,如何在docker中运行windows
  9. 【计算机三级网络】考前看一看,必过60分
  10. 深度强化学习-策略梯度算法推导
  11. java中length和length()的区别
  12. Blender展UV插件:UVSquares
  13. Arbitrum上首个跨链互操应用开启空投计划!
  14. js根据文字(保存大小,字体)计算文字长度,并根据容器显示省略号
  15. 学生实验室常见升压降压芯片电路介绍
  16. 沈阳计算机专业中专学校有哪些,沈阳市都有哪些中专学校是公立的
  17. 小米彷徨:股价与业绩的自我救赎
  18. linux服务器登录卡在last login的解决
  19. android seekbar 背景颜色,Android中自定义SeekBar如何实现分段显示不同背景颜色
  20. 【8088】基于8088最小系统板的打地鼠游戏实现【简】

热门文章

  1. 一卡易:构建最具移动消费属性的微信会员管理营销平台
  2. 【论文阅读-人机交互】A case for humans-in-the-loop:Decisions in the Presence of Erroneous Algorithmic Scores
  3. TMS320F283743之GPIO配置
  4. notepad++ PoorMansTSQLFormatter 插件安装
  5. 潜在语义分析(LSA)详解
  6. Atom 编写 Markdown 一键上传图片,使用7牛云图床
  7. C++:十进制转换为二进制
  8. 51单片机 独立键盘模块
  9. 金秋话安全 | 2021国家网络安全周天空卫士与您相约西安
  10. 南科大本科生在《物理评论快报》发文,实现由不定因果序驱动的量子冰箱