今天Java的学习内容是面向对象的三大特性:封装、继承、多态。这是Java中非常核心的内容,面试也经常考。
说实话今天内容有点多,脑子有点晕,但整理完笔记后清晰多了。下面是我今天的学习总结。
一、封装
1. 修饰符
private:私有的,只能在本类中使用public:公开的,任何地方都能用
2. 封装的要求(标准写法)
public class Student { // 1. 属性私有化 private String name; private int age; // 2. 提供公开的getter/setter方法 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; } }3. 使用方式
Student stu = new Student(); stu.setName("张三"); stu.setAge(18); System.out.println(stu.getName() + "," + stu.getAge());封装的好处:保护数据安全,控制访问权限,可以在set方法中添加逻辑校验。
二、继承
1. 概念
继承体现的是"is-a"关系:
铅笔是一种笔
狗是一种动物
语法:
class 子类 extends 父类 { }示例:
// 父类 class Animal { String name; public void eat() { System.out.println("吃东西"); } } // 子类 class Dog extends Animal { public void bark() { System.out.println("汪汪叫"); } }2. 继承的好处
提高代码复用性:子类可以直接使用父类的属性和方法
提高代码可扩展性:可以在子类中添加新功能
3. 方法覆盖(Override/重写)【面试重点】
概念:子类中定义和父类同名、同参、同返回值的方法。
要求:
方法名、参数列表、返回值类型都要相同
访问修饰符相同或更宽(
private→default→protected→public)
示例:
class Animal { public void sound() { System.out.println("动物叫"); } } class Dog extends Animal { @Override // 注解,表示这是重写,推荐加上 public void sound() { System.out.println("汪汪汪"); } }使用:子类对象调用时,优先使用子类重写后的方法。
面试题:Override 和 Overload 的区别
| 对比项 | Override(重写) | Overload(重载) |
|---|---|---|
| 关系 | 父子类之间 | 同一个类中 |
| 方法名 | 相同 | 相同 |
| 参数列表 | 必须相同 | 必须不同 |
| 返回值 | 相同 | 无要求 |
| 修饰符 | 相同或更宽 | 无要求 |
4. Java继承的特点
单继承:一个类只能有一个直接父类
但可以有多个间接父类(多级继承)
class A {} class B extends A {} // B的直接父类是A class C extends B {} // C的直接父类是B,间接父类是A5. 子类能继承父类的哪些内容?
构造方法:不能被继承(因为构造方法名必须和类名一致)
属性和方法:取决于访问修饰符
| 修饰符 | 能否被继承 |
|---|---|
private | ❌ 不能 |
default | ✅ 同包子类可以 |
protected | ✅ 可以 |
public | ✅ 可以 |
6. 创建对象的过程(继承情况下)
Dog d = new Dog();
执行顺序:
分配空间(子类 + 所有父类的空间)
递归创建父类对象(初始化父类属性 → 执行父类构造方法)
完成子类对象创建(初始化子类属性 → 执行子类构造方法)
7. super关键字【面试重点】
第一种用法:super()/super(实参)
在子类构造方法中,指示调用父类的哪个构造方法。
class Animal { public Animal() { System.out.println("父类无参构造"); } public Animal(String name) { System.out.println("父类有参构造:" + name); } } class Dog extends Animal { public Dog() { super(); // 调用父类无参构造,可以省略,JVM默认添加 System.out.println("子类无参构造"); } public Dog(String name) { super(name); // 调用父类有参构造 System.out.println("子类有参构造:" + name); } }规则:
super()必须写在构造方法第一行子类构造方法第一行如果没有
super()/this(),JVM会默认添加super()this()和super()不能同时出现在同一个构造方法中
第二种用法:super.
用于调用父类的属性或方法。
class Animal { String name = "动物"; } class Dog extends Animal { String name = "狗"; public void show() { System.out.println(name); // 狗 System.out.println(super.name); // 动物 } }三、多态
1. 多态的前提
必须有继承关系
必须有方法重写
父类引用指向子类对象
2. 多态的语法
父类类型 引用名 = new 子类类型();
示例:
Animal a = new Dog(); // 父类引用指向子类对象 a.eat(); // 调用的是子类重写后的方法
3. 多态的特点
编译看左边,运行看右边
编译时:检查父类中有没有这个方法
运行时:执行子类重写后的方法
Animal a = new Dog(); a.eat(); // ✅ 父类有eat(),运行执行Dog的eat() a.bark(); // ❌ 编译报错,父类中没有bark()方法
4. 引用类型转换
向上转型(自动)
Dog d = new Dog(); Animal a = d; // 自动转换,安全
向下转型(强制)
Animal a = new Dog(); Dog d = (Dog) a; // 强制转换,需要保证实际类型是Dog
注意:如果实际类型不匹配,会报ClassCastException
Animal a = new Dog(); Cat c = (Cat) a; // 运行报错:ClassCastException
5. instanceof 关键字
用于判断引用的实际对象类型是否兼容某个类。
Animal a = new Dog(); if (a instanceof Dog) { Dog d = (Dog) a; System.out.println("转换成功"); } if (a instanceof Cat) { Cat c = (Cat) a; // 不会执行,因为a实际上是Dog }在向下转型前,建议先用
instanceof判断,避免类型转换异常。
6. 多态的实际应用(开发重点)
用在数组上
Animal[] arr = new Animal[3]; arr[0] = new Dog(); arr[1] = new Cat(); arr[2] = new Bird();
用在方法参数上
public void feed(Animal a) { a.eat(); // 不管传什么动物,都能调用eat() } // 调用 feed(new Dog()); feed(new Cat());用在返回值上
public Animal getAnimal(int type) { if (type == 1) { return new Dog(); } else { return new Cat(); } }7. 多态的好处
屏蔽不同子类之间的差异性,统一管理
让程序更灵活、更通用
四、我踩过的坑
坑1:封装时忘记提供getter/setter
private int age; // 忘了写getAge()和setAge(),外部无法访问
解决:属性私有化后,必须提供公开的访问方法。
坑2:继承时子类构造方法没有调用父类构造方法
class Parent { public Parent(String name) { // 有参构造 } } class Child extends Parent { public Child() { // 编译报错:父类没有无参构造 } }解决:子类构造方法中显式调用父类的有参构造super(name)。
坑3:方法重写时写错参数
// 父类 public void eat() { } // 子类想重写,但写成了重载 public void eat(String food) { } // 这是重载,不是重写解决:重写时参数列表必须完全相同,建议加上@Override注解检查。
坑4:向下转型时没做instanceof判断
Animal a = new Dog(); Cat c = (Cat) a; // 运行报错
解决:转型前用instanceof判断。
总结
今天学的三大特性是面向对象的核心:
| 特性 | 关键词 | 核心要点 |
|---|---|---|
| 封装 | private+get/set | 隐藏实现细节,保护数据安全 |
| 继承 | extends | 代码复用,is-a关系,单继承 |
| 多态 | 父类引用指向子类对象 | 编译看左,运行看右,灵活通用 |
面试高频题:
Override和Overload的区别
访问修饰符的继承性
super和this的区别多态的前提和特点
instanceof的作用
我接下来的任务:把课堂上的案例都敲一遍(比如动物继承体系、图形面积计算等),加上注释,再做一些练习题巩固。
如果你也在学Java,欢迎一起交流,我们明天继续!