封装
private关键字
- 是一个权限修饰符 可以修饰成员
- 成员变量和成员方法
- 被private修饰的成员只能在本类中才能访问
针对private修饰的成员变量,如果需要被其他类使用,提供相应的操作
- 提供“get变量名()”方法,用于获取成员变量的值,方法用public修饰
- 提供“set变量名(参数)”方法,用于设置成员变量的值,方法用public修饰
this关键字:代表所在类的对象引用
- 本质:方法被哪个对象调用,this就代表哪个对象
- 局部变量和成员变量如果重名,Java使用的是就近原则
- this关键字,可以调用本类的成员(变量, 方法),解决局部变量和成员变量的重名问题
面向对象三大特征:
- 封装:private只是封装的一种体现
- 举例1:将代码抽取到方法中,这是对代码的一种封装
- 举例2:将属性抽取到类当中,这是对数据的一种封装
继承
继承概述:
- 让类与类之间产生关系(子父类关系),子类可以直接使用父类中的,非私有成员
- 子类也可称为"派生类",父类也可称为"基类"、“超类”
继承格式:
- 使用extends关键字
public class 子类名 extends 父类名{}
- 特点是:单继承,多层继承,继承具有传递性(例如:爷爷、爸爸、儿子)
- 继承的访问特点:就近原则(局部,本类,父类)
继承的好处:
- 提高了代码的复用性
- 提供了代码的维护性
- 让类与类之间产生了关系,是多态的前提
继承的弊端:
- 继承是侵入性的
- 降低了代码的灵活性:子类必须拥有父类非私有成员,增加了子类的约束
- 增强了代码之间的耦合性:代码与代码之间的关联称为"耦合性"
继承的应用场景:
-
当类与类之间,存在相同(共性)内容时
-
并且产生了"is a"的关系(student is a person、teacher is a person)
-
Java只支持单继承,不支持多继承;但是可以多层继承(形成继承体系)
一个儿子只有一个爸爸(亲的),不能有多个爸爸,爸爸也只有一个爸爸(儿子的爷爷)
Java为什么不支持多继承:
父类中可能存在,同名的成员方法,完成了不同逻辑,如果支持多继承,在子类中造成逻辑混乱
两个爸爸的同名方法,干了不同的事,这时候到底听谁的??
什么是重写?
- 子类和父类具有两个完全相同的方法(返回值类型,参数列表一致)
- 四种权限修饰符:(从小到大)private -> 默认 -> protected -> public
需同时满足的条件 - 多个方法在同一个类中
- 多个方法具有相同的方法名
- 多个方法的参数不相同,类型不同或者数量不同
方法重写的应用场景:
当子类需要父类功能时,而功能主体子类需要有特有的功能 可以重写父类中的方法,这样既沿袭了父类功能,又定义了子类特有的功能
public class Phone01 {
//一代电话,只能打电话
public void call(String name){
System.out.println("给"+name+"打电话");
}
}
public class Phone02 extends Phone01 {
//二代电话,打电话之前,可以开视频
@Override
public void call(String name){
System.out.println("开启视频功能...");
//System.out.println("给"+name+"打电话...");
super.call("吴彦祖");//两种写法都可以
}
}
public class PhoneTest {
public static void main(String[] args) {
//创建对象
Phone01 p1 = new Phone01();
p1.call("吴彦祖");
System.out.println("------------------");
//创建二代对象
Phone02 p2 = new Phone02();
p2.call("陈冠希");
}
}
方法重写的注意事项
- 注意1. 父类中的私有方法不能被重写(父类私有的内容子类访问不到,访问不到就不能重写)
- 注意2. 父类静态方法,子类必须通过静态方法"重写";父类非静态方法,子类必须通过非静态方法"重写" 结论:静态不静态,子父类统一
- 注意3. 静态方法不能被重写! 强行重写静态方法,子类必须是静态,现象上和重写效果一样,但是本质不同
可以理解为,子类将父类中的同名方法隐藏,而非重写(从哪看:@Override注解报错)- 注意4. 子类重写父类方法时,访问权限必须大于等于父类方法 public > protected(保护子类) > 默认不写(包权限)> private
- 注意5. @Override注解: 位置是,声明在重写父类方法的子类方法上 作用是,检查该方法,重写是否正确,不正确则报错
抽象类:
- 不能创建对象,用来继承子类强制重写的抽象方法
final关键字的特点:
- 类:被final修饰的类为最终类,不能被继承
- 方法:最终方法,不能被重写
- 变量:会变成常量,命名规则为纯大写(NUM)
- 基本数据类型:其值不能被修改
- 引用数据类型:地址不能被修改,但是里面的数据可以修改
代码块:
- 局部代码块
- 构造代码块(每个构造方法执行前都会先执行)
- 静态代码块(只执行一次,伴随着类的加载儿运行
多态
什么是多态?
同一个对象,在不同时刻表现出来的不同形态
- 例如:猫可以叫猫,也可以叫做动物 多态的前提是:要有继承关系、重写方法、父类引用指向子类对象
class Animal {
public void eat(){
System.out.println("动物吃饭");
}
}
class Cat extends Animal {
@Override
public void eat() {
System.out.println("猫吃鱼");
}
}
public class Test1Polymorphic {
/*
多态的前提:
1. 要有(继承 \ 实现)关系
2. 要有方法重写
3. 要有父类引用, 指向子类对象
*/
public static void main(String[] args) {
// 当前事物, 是一只猫
Cat c = new Cat();
// 当前事物, 是一只动物
Animal a = new Cat();
a.eat();
}
}
成员访问特点:
- 成员变量:编译看父类,运行看父类
- 成员方法:编译看父类,运行看子类(因为子类重写父类方法)
多态的好处:
- 提高程序的扩展性,定义方法的时候,使用父类型作为参数,再使用的时候,使用具体子类型参与操作
- 弊端:不能使用子类的特有成员
多态中的转型:
- 向上转型:父类引用指向子类(等同于隐式转换)
- 向下转型:格式 -> 子类型 对象名 = (子类型)父类引用
class Fu {
public void show(){
System.out.println("Fu..show...");
}
}
class Zi extends Fu {
@Override
public void show() {
System.out.println("Zi..show...");
}
public void method(){
System.out.println("我是子类特有的方法, method");
}
}
public class Test3Polymorpic {
public static void main(String[] args) {
// 1. 向上转型 : 父类引用指向子类对象
Fu f = new Zi();
f.show();
// 多态的弊端: 不能调用子类特有的成员
// f.method();
// A: 直接创建子类对象
// B: 向下转型
// 2. 向下转型 : 从父类类型, 转换回子类类型
Zi z = (Zi) f;
z.method();
}
}
多态中转型存在的风险和解决方案:
- 风险:如果被强转的引用类型变量,对应的实际类型和目标类型不是同一种类型,那么在转换的时候机会出现ClassCastException
- 解决方案:关键字 / 格式 -> 变量名 instanceof 类型
理解:就是判断关键字左边的变量,是否是右边的类型,返回Boolean类型结果
abstract class Animal {
public abstract void eat();
}
class Dog extends Animal {
public void eat() {
System.out.println("狗吃肉");
}
public void watchHome(){
System.out.println("看家");
}
}
class Cat extends Animal {
public void eat() {
System.out.println("猫吃鱼");
}
}
public class Test4Polymorpic {
public static void main(String[] args) {
useAnimal(new Dog());
useAnimal(new Cat());
}
public static void useAnimal(Animal a){
a.eat();
// 判断a变量记录的类型, 是否是Dog
if(a instanceof Dog){
Dog dog = (Dog) a;
dog.watchHome();
}
}
}