学习日记-day13-5.22
完成目标:
知识点:
1.抽象注意事项
知识点 | 核心内容 | 重点 |
抽象类实例化限制 | 抽象类不能直接实例化对象,只能创建非抽象子类的对象 | 尝试实例化抽象类会触发编译错误 |
抽象方法与抽象类关系 | 抽象类不一定包含抽象方法,但含抽象方法的类必须是抽象类 | 定义顺序影响类声明(先有抽象方法需声明抽象类) |
子类重写要求 | 子类必须重写父类所有抽象方法,否则需声明为抽象类 | 漏写重写方法等价于隐含继承父类抽象方法 |
抽象类成员结构 | 可包含成员变量/构造方法/普通方法,与普通类差异仅在于抽象方法 | 构造方法用于子类初始化父类属性(非自身实例化) |
构造方法作用机制 | 抽象类构造方法专用于子类对象初始化时设置父类属性 | 通过super()调用父类构造方法实现属性传递 |
2.抽象实例
某IT公司有多名员工,按照员工负责的工作不同,进行了部门的划分(研发部、维护部)。
研发部(Developer)根据所需研发的内容不同,又分为 JavaEE工程师 、Android工程师 ;
维护部(Maintainer)根据所需维护的内容不同,又分为 网络维护工程师(Network) 、硬件维护工程师(Hardware) 。
公司的每名员工都有他们自己的员工编号、姓名,并要做它们所负责的工作。
工作内容:
- JavaEE工程师: 员工号为xxx的 xxx员工,正在研发电商网站
- Android工程师:员工号为xxx的 xxx员工,正在研发电商的手机客户端软件
- 网络维护工程师:员工号为xxx的 xxx员工,正在检查网络是否畅通
- 硬件维护工程师:员工号为xxx的 xxx员工,正在修复电脑主板
根据描述,完成员工体系中所有类的定义,并指定类之间的继承关系。进行XX工程师类的对象创建,完成工作方法的调用。
public abstract class Employee {private int id;private String name;public Employee() {}public Employee(int id, String name) {this.id = id;this.name = name;}public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public abstract void work();
}```
public abstract class Developer extends Employee{
}
public class JavaEE extends Developer{@Overridepublic void work() {//System.out.println("员工号为:"+getId()+"的"+getName()+"正在开发网站");System.out.println("员工号为:"+this.getId()+"的"+this.getName()+"正在开发网站");}
}
public class Android extends Developer{@Overridepublic void work() {//System.out.println("员工号为:"+getId()+"的"+getName()+"正在开发app");System.out.println("员工号为:"+this.getId()+"的"+this.getName()+"正在开发app");}
}
public class Test01 {public static void main(String[] args) {JavaEE javaEE = new JavaEE();javaEE.setId(1);javaEE.setName("涛哥");javaEE.work();System.out.println("===============");Android android = new Android();android.setId(2);android.setName("金莲");android.work();}
}
3.接口
知识点 | 核心内容 | 重点 |
接口定义 | 使用interface关键字定义引用数据类型,是一种标准/规范 | 接口与抽象类的区别; 接口成员默认修饰符规则 |
接口实现 | 通过implements关键字创建实现类; 必须重写所有抽象方法 | 实现类与子类概念区分; 接口不能直接实例化 |
JDK7接口特性 | 仅包含: - public abstract抽象方法; - public static final常量 | 抽象方法修饰符可省略; 常量必须初始化 |
JDK8新增特性 | 支持: - default默认方法(带实现); - static静态方法 | 默认方法冲突解决规则; 静态方法接口专属调用方式 |
多态应用 | 通过接口引用指向实现类对象; Mouse m = new Mouse() | 运行时绑定机制; 类型转换异常风险点 |
生活化案例 | 插座/USB接口类比: - 统一标准; - 强制规范 | 接口设计开闭原则体现; 扩展性vs约束性平衡 |
1.定义接口:
public interface 接口名{}
2.实现:
public class 实现类类名 implements 接口名{}
3.使用:
a.实现类实现接口
b.重写接口中的抽象方法
c.创建实现类对象(接口不能直接new对象)
d.调用重写的方法
public interface USB {public abstract void open();public abstract void close();
}public class Mouse implements USB{@Overridepublic void open() {System.out.println("鼠标打开");}@Overridepublic void close() {System.out.println("鼠标关闭");}
}public class Test01 {public static void main(String[] args) {Mouse mouse = new Mouse();mouse.open();mouse.close();}
}
4.默认方法 静态方法
知识点 | 核心内容 | 重点 |
默认方法 | JDK8新增特性,格式为public default 返回值 方法名(),包含方法体实现,可通过实现类对象调用 | 1. 与抽象方法区别:有方法体; 2. 可重写可不重写; 3. 必须通过实现类调用 |
静态方法 | JDK8新增,格式为public static 返回值 方法名(), 直接通过接口名调用 | 1. 不需要实现类; 2. 调用方式与类静态方法相同 |
应用场景 | 1. 作为临时添加的小功能; 2. 避免因添加抽象方法导致所有实现类报错 | 1. 默认方法:功能扩展; 2. 静态方法:工具类功能 |
语法注意点 | 1. 实现类重写默认方法时不能加default关键字; 2. 静态方法不能被实现类继承或重写 | 1. @Override注解可验证重写; 2. 接口静态方法 vs 类静态方法调用方式 |
5.接口的成员变量
知识点 | 核心内容 | 重点 |
接口中的成员变量定义 | 使用public static final修饰成员变量(如int NUM=100),默认隐含该修饰,需手动初始化 | final变量的不可变性、默认修饰符规则 |
静态成员调用方式 | 通过接口名直接调用静态变量(如USB.NUM) | 接口与类静态成员调用语法的区别 |
开发规范 | static final修饰的变量名需全大写(如NUM而非num) | 命名习惯与实际语法约束的差异 |
final关键字的特性 | 被修饰变量为常量,禁止二次赋值 | final与普通变量的初始化要求对比 |
6.接口特点和与抽象类的区别
知识点 | 核心内容 | 重点 |
接口特点 | 1. 可以多继承(一个接口继承多个接口); 2. 可以多实现(一个类实现多个接口); 3. 子类可同时继承父类和实现接口 | 接口继承 vs 类继承; 类单继承 vs 接口多继承 |
接口实现注意事项 | 1. 多个接口抽象方法重名时只需重写一次; 2. 多个接口默认方法重名时必须重写 | 抽象方法冲突只需实现一次; 默认方法冲突强制重写 |
接口与抽象类区别 | 相同点: - 都位于继承体系顶端; - 都不能实例化; - 都包含抽象方法; 不同点: - 抽象类可包含成员变量/构造方法; - 接口侧重功能集合 | 设计定位差异: 抽象类→父类扩展; 接口→功能契约 |
命名规范 | 实现类推荐使用Impl后缀(implements缩写) | 开发中通过命名快速识别实现类 |
代码示例 | interface A extends B,C; class Impl implements A,B; class Sub extends Parent implements A,B | 多继承语法糖写法 |
7.多态
知识点 | 核心内容 | 重点 |
多态概念 | 面向对象三大特征之一,强调方法重写和父类引用指向子类对象 | 不要从字面理解"一个事物多种形态",要从使用形式理解 |
多态前提条件 | 1. 必须有子父类继承或接口实现关系; 2. 必须有方法重写(无重写则多态无意义) | 成员变量在多态中无意义,重点关注重写方法 |
多态实现方式 | 父类类型 变量名 = new 子类构造器(); 类比基本数据类型转换:double b = 10(大类型接收小类型) | 与常规new对象方式(Dog d = new Dog())的语法区别 |
多态调用限制 | 不能直接调用子类特有功能; 只能调用重写方法和父类定义的方法 | 与继承中new父类对象不能调子类方法的规则一致 |
多态应用示例 | Animal a = new Dog(); a.eat()调用的是Dog重写方法; Animal a2 = new Cat(); a2.eat()调用Cat重写方法 | 编译看左边,运行看右边的调用机制 |
多态专业术语 | 英文术语:Polymorphic; 代码特征:抽象类/接口+实现类重写 | 需区分抽象类与接口的实现方式差异 |
多态实现:
public abstract class Animal {public abstract void eat();
}public class Dog extends Animal{@Overridepublic void eat() {System.out.println("狗啃骨头");}//特有方法public void lookDoor(){System.out.println("狗会看门");}
}public class Cat extends Animal{@Overridepublic void eat() {System.out.println("猫吃鱼");}//特有方法public void catchMouse(){System.out.println("猫会捉老鼠");}
}public class Test01 {public static void main(String[] args) {//原始方式Dog dog = new Dog();dog.eat();//重写的dog.lookDoor();//特有的Cat cat = new Cat();cat.eat();//重写的cat.catchMouse();//特有的System.out.println("==================");//多态形式new对象Animal animal = new Dog();//相当于double b = 10animal.eat();//重写的 animal接收的是dog对象,所以调用的是dog中的eat
// animal.lookDoor(); 多态前提下,不能直接调用子类特有成员Animal animal1 = new Cat();animal1.eat();//cat重写的}
}
8.多态_成员访问特点
知识点 | 核心内容 | 重点 |
多态成员的访问特点 | 成员变量访问看等号左边(编译类型),成员方法调用看new的对象(运行类型) | 成员变量无多态性(输出1000),成员方法有多态性(输出子类重写方法) |
继承口诀应用 | 成员变量:看左边(父类);成员方法:看new谁(子类优先) | 易混淆变量与方法的访问规则差异 |
多态本质 | 主要玩方法重写,不涉及成员变量的多态性 | 实际开发中强调方法重写的优先级 |
9.多态的优点
知识点 | 核心内容 | 重点 |
多态的定义与形式 | 父类引用指向子类对象(Animal a = new Dog()),通过父类类型调用子类重写方法 | 多态与原始方式(Dog d = new Dog())的语法区别 |
多态的优缺点对比 | 优点:扩展性强(父类类型可接收任意子类对象); 缺点:无法直接调用子类特有成员 | 原始方式 vs 多态方式的调用权限差异(重写/继承/特有方法) |
扩展性案例 | 方法形参定义为父类类型(void method(Animal a)),可传递不同子类对象(Dog/Cat),调用各自重写方法 | 原始方式需为每个子类单独定义方法(method(Dog d), method(Cat c)) |
多态的应用场景 | 框架开发、对象传递时优先使用多态,核心价值是统一调用重写方法,而非调用子类特有功能 | 易混淆点:多态并非为调用特有功能设计 |
类型转换与接收范围 | 类比double b = 10(大类型接收小类型),多态中父类类型可接收所有子类对象 | 类型不匹配时的编译错误(如Dog d = new Cat()) |
在开发实践中:多态是许多设计模式的基础;多数Java框架底层都使用多态机制