3.4 面向对象编程高级 【重点!】 万字抽象类与接口笔记-跟着韩老师学JavaSE

大佬给推荐的韩顺平老师的课程 2021年刚刚录的船新版本!
【零基础 快速学Java】韩顺平 零基础30天学会Java
我整理的学习路线与各章节学习笔记戳这里
硬把从另一个讲师那里看了300多集的我拽过来 几十节课一下子爱上这个节奏了!安利!!

具有其他语言基础的盆友只需要把前几章的章节总结简单看一下 然后再去着重看需要学习的章节就可以了!
知识点分的非常清晰! 每章还有总结 这…真的是我理想中的学习资料呐!

学习笔记整理过后放到这里

  • 一方面是让自己再二次记忆一下
  • 一方面是希望可以帮到有这方面知识需要的朋友 给他们一个新的切入点来重新了解这一个知识

本专题包括以下几个主要知识点~
3.4 面向对象编程高级 【重点!】 万字抽象类与接口笔记-跟着韩老师学JavaSE_第1张图片
本次笔记主要记录 抽象类接口的内容
这两部分是非常重点的作用 同时这两者也是有一些关联的 让我们看看这两个部分的内容吧

文章目录

  • 6.抽象类
    • 【1】抽象类引出
      • 抽象类具体介绍
    • 【2】抽象类细节
      • 1.抽象类不能被实例化
      • 2.抽象类不一定要包含abstract方法
      • 3.一旦类包含了abstract方法 这个类必须生命为abstract
      • 4.abstract只能修饰类和方法 不能修饰属性和其他的内容
      • 5.抽象类可以有任意成员 抽象类的本质还是类哦!
      • 6.抽象方法不能有主体!也就是不能被实现!
      • 7.如果一个类继承了抽象类 则它要不实现抽象类的==所有==抽象方法 要么自己也声明为抽象类
      • 8.抽象方法不能用private final static来修饰!因为这些关键字定义的方法不让重写啊!!
    • 【3】抽象类课堂练习
    • 【4】超棒的抽象类实践-模板设计模式
      • 1.基本介绍
      • 2.模板设计模式能解决的问题
      • 3.来实践一下吧!
        • 需求
        • 实现思路
      • 代码实现
  • 7.接口
    • 【1】快速入门接口
    • 【2】接口基本介绍
      • 接口基本介绍小结
    • 【3】接口应用场景
    • 【4】接口使用细节
      • 1.接口不能被实例化
      • 2.接口中所有的方法是public方法 & 接口中的抽象方法是默认的 不需要abstract修饰了
      • 3.1 一个普通类实现接口就必须将接口的所有方法都实现
      • 3.2 抽象类实现接口可以不用实现接口的方法
      • 4.一个类可以同时实现多个接口
      • 5.接口中的属性只能是final的
      • 6.接口中属性的访问性质
      • 7.接口不能继承其他的类 但是可以继承多个别的接口
      • 8.接口的修饰符只能是public和默认
    • 【5】接口课堂练习-1
    • 【6】接口 VS 继承
    • 【7】接口多态特性
      • 1.多态参数
      • 2.多态数组
    • 【8】接口多态传递
    • 【9】接口课堂练习-2
    • 【10】类的五大成员小结

6.抽象类

【1】抽象类引出

先来看一段代码

class Animal{
    private String name;
    private int age;//属性定义
    public Animal(String name, int age){
        //含参构造器
        super();
        this.name = name;
        this.age = age;
    }
    //动物都有eat的行为
    public void eat(){
        System.out.println("这里是某只动物 但是由于不清楚品种 所以目前不知道要吃啥 eat方法先声明着哈");       
    }
    //上面这种方法的声明并没有啥意义哦!
    
    public abstract void eat();
}

可以看到 这个 eat()方法就是先声明出来 但是不确定如何实现

总结下

父类Animal中某些方法 需要声明但又不确定如何实现时 可以将其生命为抽象方法 那么这个父类Animal就是抽象类

抽象类具体介绍

  • 用abstract关键字来修饰一个类时 这个类就叫抽象类
访问修饰符 abstract 类名{}
  • 用abstract关键字来修饰一个方法时 这个方法就是抽象方法
访问修饰符 abstract 返回类型 方法名(参数列表);
//没有方法体哦!!
  • 抽象类的价值更多作用是在于设计 设计者设计好抽象类让子类继承并具体实现这个抽象类

  • 抽象类是面试官比较爱问的知识点哦! 框架和设计模式中使用得较多!

【2】抽象类细节

1.抽象类不能被实例化

public class AbstractDetail01 {
	public static void main(String[] args) {
		//抽象类A 不能被实例化
		//new A();
	}
}

abstract class A {
	public void hi() {
		System.out.println("hi");
	}
}

2.抽象类不一定要包含abstract方法

抽象类中可以没有abstract方法哦!

abstract class A {
	public void hi() {
		System.out.println("hi");
	}
}

3.一旦类包含了abstract方法 这个类必须生命为abstract

4.abstract只能修饰类和方法 不能修饰属性和其他的内容

5.抽象类可以有任意成员 抽象类的本质还是类哦!

比如 非抽象方法 构造器 静态属性啥的 都星~

6.抽象方法不能有主体!也就是不能被实现!

请添加图片描述
这里抽象方法有了方法体 所以肯定会报错啦

7.如果一个类继承了抽象类 则它要不实现抽象类的所有抽象方法 要么自己也声明为抽象类

abstract class E {
	public abstract void hi();
}

abstract class F extends E {
    //这样不行!
}

class G extends E {
@Override
	public void hi() { 
    	//这里相等于 G 子类实现了父类 E 的抽象方法
    	//所谓实现方法,就是有方法体
	}

8.抽象方法不能用private final static来修饰!因为这些关键字定义的方法不让重写啊!!

3.4 面向对象编程高级 【重点!】 万字抽象类与接口笔记-跟着韩老师学JavaSE_第2张图片

【3】抽象类课堂练习

【零基础 快速学Java】韩顺平 零基础30天学会Java_哔哩哔哩_
3.4 面向对象编程高级 【重点!】 万字抽象类与接口笔记-跟着韩老师学JavaSE_第3张图片
第四题——

超级好的一个例子哈!

抽象这个work方法 在设计虚拟类的时候就先不用考虑不同的员工对应的work方法内容不同该咋实现了!先定义抽象方法就行!

public class AbstractExercise01 {
	public static void main(String[] args) {
		//测试
		Manager jack = new Manager("jack", 999, 50000);
		jack.setBonus(8000);
		jack.work();
		CommonEmployee tom = new CommonEmployee("tom", 888, 20000);
		tom.work();
	}
}


abstract public class Employee {
    //开始写抽象类Employee
	private String name;
	private int id;
	private double salary;
	public Employee(String name, int id, double salary) {
		this.name = name;
		this.id = id;
		this.salary = salary;
	}
	//将 work 做成一个抽象方法
	public abstract void work();
	
    //6个 getter setter方法
    public String getName() {
		return name;
	}
    
	public void setName(String name) {
		this.name = name;
	}
    
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public double getSalary() {
		return salary;
	}
	public void setSalary(double salary) {
		this.salary = salary;
	}

}

public class Manager extends Employee {
    //继承抽象类后 要实现所有抽象方法!
	private double bonus;
	public Manager(String name, int id, double salary) {
		super(name, id, salary);
	}
	public double getBonus() {
		return bonus;
	}
	public void setBonus(double bonus) {
		this.bonus = bonus;
	}
	@Override
	public void work() {
		System.out.println("经理 " + getName() + " 工作中...");
	}
}

public class CommonEmployee extends Employee{
    //继承抽象类后 要实现所有抽象方法!
	public CommonEmployee(String name, int id, double salary) {
		super(name, id, salary);
	}
	@Override
	public void work() {
		System.out.println("普通员工 " + getName() + " 工作中...");
	}
}

【4】超棒的抽象类实践-模板设计模式

二刷建议详细走一遍视频 跟着敲一下代码!
这个实践真的非常棒!可以帮助我们强化抽象类的思想!

推荐练习的一个案例 强化抽象类的思想!

1.基本介绍

抽象类体现的就是一种模板模式的设计 (抽象类作为多个子类的通用模板

子类在抽象类的基础上进行扩展、改造 但是子类总体上会保留抽象类的行为方式

2.模板设计模式能解决的问题

  • 功能内部一部分实现是确定的 但是一部分实现是不确定的时候 可以把不确定的部分暴露出去让子类去实现!
  • 编写一个抽象父类(提供了多个子类的通用方法 并把一个或多个方法留给其子类实现) 这个过程就是一种模板模式

3.来实践一下吧!

需求

1.有多个类 用于完成不同的任务 job

2.要求统计得到各自完成任务的时间

编程实现这个抽象类吧!

实现思路

3.4 面向对象编程高级 【重点!】 万字抽象类与接口笔记-跟着韩老师学JavaSE_第4张图片
具体的设计细则如下——
3.4 面向对象编程高级 【重点!】 万字抽象类与接口笔记-跟着韩老师学JavaSE_第5张图片

代码实现

template是 模板 的意思~

在这个案例中 我们假设需要给很多很多工作计算工作时间!

其中 计算工作时间的方法 可以写一个统一的方法 calculateTime()

而每一个工作不同的地方

abstract public class Template { //抽象类-模板设计模式
	public abstract void job();//抽象方法
	public void calculateTime() {//实现方法,调用 job 方法
		//得到开始的时间
		long start = System.currentTimeMillis();
		job(); //复习下动态绑定机制——
        //虚拟机调用实例方法job()时,它会基于对象实际的类型(只能在运行时得知)来选择所调用的方法job()的具体内容,这就是动态绑定,是多态的一种。
        //在这里就是 根据子类重写的对象 来确定job()的具体内容~
		
        //得的结束的时间
		long end = System.currentTimeMillis();
		System.out.println("任务执行时间 " + (end - start));
	}
}

public class AA extends Template {
	//计算任务
	//1+....+ 800000
	@Override
	public void job() { 
        //实现 Template 的抽象方法 job
        //方法内容是 进行80w次循环 
        //除了实现这个抽象方法 其他的方法都不用写了!方便!!
		long num = 0;
		for (long i = 1; i <= 800000; i++) {
			num += i;
        }
	}
}

public class BB extends Template{
	public void job() {//这里也去重写了 Template 的 job 方法 循环8w次
		long num = 0;
		for (long i = 1; i <= 80000; i++) {
			num *= i;
		}
	}
}

public class TestTemplate {
	public static void main(String[] args) {
		AA aa = new AA();
		aa.calculateTime(); //这里还是需要有良好的 OOP 基础,尤其是对多态的理解
        
        //我们不需要在AA类中编写具体的计算工作时间的方法
        //只需要把AA类中简单的“工作内容”这部分的代码编写好 剩下的用抽象类中的方法即可完成要求!!
        //各个类中的代码量大大减少!!
		BB bb = new BB();
		bb.calculateTime();
	}
}

可以看看之前的代码 复用性极差!

public class AA{
    
	public void job() {
    //反面教材! : 每个类都去实现 计算工作时间的方法
		// 得到开始的时间
		long start = System.currentTimeMillis();
		long num = 0;

        //任务具体内容 
        //用到了抽象类之后 AA类中只要实现这部分就OK了!
		for (long i = 1; i <= 200000; i++) {
			num += i;
		}
        
		// 得的结束的时间
		long end = System.currentTimeMillis();
        // 相减即可得到类中方法执行时间
		System.out.println("AA 执行时间 " + (end - start));
	}
}

上面的抽象类这么一看真是香得一批啊!

体现了模板设计模式——对代码的简洁性和复用性有很大的帮助哦!

这里一定要好好看 认真理解哦!

7.接口

下面来学习接口的内容

https://www.bilibili.com/video/BV1fh411y7R8?p=403&spm_id_from=pageDriver

【1】快速入门接口

老韩举了一个很形象的例子

电脑的USB 分别连接 手机和照相机等
3.4 面向对象编程高级 【重点!】 万字抽象类与接口笔记-跟着韩老师学JavaSE_第6张图片
分别要完成这些代码 即可完成一次接口的应用
3.4 面向对象编程高级 【重点!】 万字抽象类与接口笔记-跟着韩老师学JavaSE_第7张图片

【2】接口基本介绍

经过这个形象的例子快速入门之后 来看看接口到底是个啥

  • 接口就是给出一些没有实现的方法 并将它们封装到一起 某个类(即前面提到的手机类、照相机类)要使用这些方法的时候 根据具体情况在类中把这些方法写出来就行~

    各自的语法如下:

    • 接口类
    interface 接口名{
        //属性
        //抽象方法
    }
    

3.4 面向对象编程高级 【重点!】 万字抽象类与接口笔记-跟着韩老师学JavaSE_第8张图片

  • 使用接口的类
class 使用接口的类 implements 接口{
    自己的属性与方法;
    必须实现的接口的抽象方法;
}

3.4 面向对象编程高级 【重点!】 万字抽象类与接口笔记-跟着韩老师学JavaSE_第9张图片

接口基本介绍小结

  • 接口是更加抽象的抽象类

抽象类中的方法可以有方法体!(当然了抽象方法也是不可以有方法体的~)但是接口里的所有方法都没有方法体【jdk7.0】

注意~ jdk8.0之后 接口类可以有静态方法、默认方法

也就是接口中可以有方法的具体实现

【3】接口应用场景

接口的概念并不难 难的是“要清楚什么时候使用接口”

举几个例子——
3.4 面向对象编程高级 【重点!】 万字抽象类与接口笔记-跟着韩老师学JavaSE_第10张图片
3.4 面向对象编程高级 【重点!】 万字抽象类与接口笔记-跟着韩老师学JavaSE_第11张图片

【4】接口使用细节

1.接口不能被实例化

2.接口中所有的方法是public方法 & 接口中的抽象方法是默认的 不需要abstract修饰了

之前我们在抽象类定义抽象方法还得要

public abstract void aa();

而接口中默认所有方法都是public方法 且 是抽象的了(不知道jdk8.0还是不是这样哈 在jdk7.0之前都是这样亚子的!)

void aa();//默认是public 抽象 的方法

3.1 一个普通类实现接口就必须将接口的所有方法都实现

注意是所有方法哦!都要实现!不然会报错

3.2 抽象类实现接口可以不用实现接口的方法

如果是个抽象类就不用像3.1中一样实现所有方法了

4.一个类可以同时实现多个接口

按理说 Java是不支持类的多重继承的 一个类只能继承一个类

但是!如果搬到接口这里 一个类可以继承多个接口 这也算是某种程度上达到了多重继承!

5.接口中的属性只能是final的

int a = 1;
public static final int a = 1;
//在接口中这两个定义属性a的方法是等价的
//(戏真多啊...)

复习下final修饰符的作用——修饰类中的某个不希望被修改的属性值

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Vhmzrcjp-1627996818143)(03 面向对象高级.assets/image-20210803193642404.png)]

6.接口中属性的访问性质

接口名.属性名;

7.接口不能继承其他的类 但是可以继承多个别的接口

interface A extends B,C{
    //B C都是接口 嗯!
}

8.接口的修饰符只能是public和默认

这点和类的修饰符是一样的!普通的类也只是用public和默认修饰符 因为用protected和private来修饰也没啥意义不是么~

interface A{}
public interface A{}

【5】接口课堂练习-1

https://www.bilibili.com/video/BV1fh411y7R8?p=408
3.4 面向对象编程高级 【重点!】 万字抽象类与接口笔记-跟着韩老师学JavaSE_第12张图片

【6】接口 VS 继承

重头戏来了!
我们来探究下接口和继承解决问题的不同

  • 继承的价值主要在于:解决代码的复用性和可维护性
  • 接口的价值主要在于:设计!我们的设计者设计好各种规范(抽象方法)然后让其他类去实现这些方法 更加灵活~

另外还有很重要的一点!接口比继承更加灵活!!

  • 继承满足 is-a 的关系 即继承了B的A类一定要是B才行!!

    人不能继承Dog类 不满足is-a关系 而柯基、吉娃娃就可以~

  • 接口只需要满足 like-a 的关系 实现接口是对Java单继承机制的一个重要补充!它让程序设计更加灵活!

    看下面这个例子 小猴子可以使用Fishable Birdable的接口

//猴子
class Monkey {
    private String name;
	public Monkey(String name) {
		this.name = name;
	}
	public void climbing() {
		System.out.println(name + " 会爬树...");
	}
	public String getName() {
		return name;
	}
}
//接口
interface Fishable {
	void swimming();
}
interface Birdable {
	void flying();
}
//继承
//小结: 当子类继承了父类,就自动的拥有父类的功能
// 如果子类需要扩展功能,可以通过实现接口的方式扩展. 
// 可以理解 实现接口 是 对 java 单继承机制的一种补充.

class LittleMonkey extends Monkey implements Fishable,Birdable {
	public LittleMonkey(String name) {
		super(name);
	}
	@Override
	public void swimming() {
		System.out.println(getName() + " 通过学习,可以像鱼儿一样游泳...");
	}
	@Override
	public void flying() {
		System.out.println(getName() + " 通过学习,可以像鸟儿一样飞翔...");
	}
}

可以看到上面的小猴子类是可以继承猴子类的同时使用接口Fishable Birdable

测试一下

public class ExtendsVsInterface {
	public static void main(String[] args) {
		LittleMonkey wuKong = new LittleMonkey("悟空");
		wuKong.climbing();
		wuKong.swimming();
		wuKong.flying();
	}
}

这些方法都是可以使用的!
3.4 面向对象编程高级 【重点!】 万字抽象类与接口笔记-跟着韩老师学JavaSE_第13张图片

  • 另外 接口在一定程度上可以实现代码接口 【即 接口规范性 + 动态绑定机制】

【7】接口多态特性

1.多态参数

接口是可以体现出多态参数的!

前面有说过这个~

在前面的Usb接口案例中 我们使用——
3.4 面向对象编程高级 【重点!】 万字抽象类与接口笔记-跟着韩老师学JavaSE_第14张图片
如图所示的work方法时

传入的实参可以是手机对象实例也可以是照相机对象实例——
3.4 面向对象编程高级 【重点!】 万字抽象类与接口笔记-跟着韩老师学JavaSE_第15张图片

这说明接口体现了多态参数!(形参既可以接收手机对象 又可以接收相机对象)

学术一点说就是:接口引用usbInterface可以指向接口的类的对象cameraphone

2.多态数组

请添加图片描述
USB接口

interface Usb{
	void work();
}
public class InterfacePolyArr {
	public static void main(String[] args) {
		//多态数组 -> 接口类型数组
		Usb[] usbs = new Usb[2];
		usbs[0] = new Phone_();
		usbs[1] = new Camera_();
		/*
		给 Usb 数组中,存放 Phone 和 相机对象,Phone 类还有一个特有的方法 call(),
		请遍历 Usb 数组,如果是 Phone 对象,除了调用 Usb 接口定义的方法外,
		还需要调用 Phone 特有方法 call
		*/
		for(int i = 0; i < usbs.length; i++) {
			usbs[i].work();//动态绑定.. //和前面一样,我们仍然需要进行类型的向下转型
			if(usbs[i] instanceof Phone_) {//判断他的运行类型是 Phone_
			((Phone_) usbs[i]).call();
		}
	}
}

【8】接口多态传递

啥是接口的多态传递?

上代码

/**
* 演示多态传递现象
*/
public class InterfacePolyPass {
	public static void main(String[] args) {
		//接口类型的变量可以指向,实现了该接口的类的对象实例
		IG ig = new Teacher();
		//如果 IG 继承了 IH 接口,而 Teacher 类实现了 IG 接口
		//那么,实际上就相当于 Teacher 类也实现了 IH 接口.
        //这就是所谓的 接口多态传递现象. 
        IH ih = new Teacher();
	}
}

interface IH {
	void hi();
}
interface IG extends IH{}
class Teacher implements IG {
	@Override
	public void hi() {
	}
}

【9】接口课堂练习-2

https://www.bilibili.com/video/BV1fh411y7R8?p=412

3.4 面向对象编程高级 【重点!】 万字抽象类与接口笔记-跟着韩老师学JavaSE_第16张图片

【10】类的五大成员小结

下面为后面要学习的内容做一个预告~

  • 属性
  • 方法
  • 构造器
  • 代码块
  • 内部类

内部类——程序员技术水平的一个分水岭!

学好内部类 我们对面向对象的认识可以再上一个台阶!!
下面的章节中我们将针对内部类进行学习

你可能感兴趣的:(#,跟着韩老师扎实学Java,Java开发学习之路,面向对象,java,接口,抽象类)