今日内容
零、 复习昨日
一、final
二、static
三、多态
四、向上转型&向下转型
五、多态应用
零、 复习昨日
0 类封装步骤
- 属性私有private
- 提供setget方法
1 继承关键词,继承的好处
- extends
- 减少代码重复
- 为多态做准备
2 子类可以使用父类什么
- 非私有的属性和方法
3 方法重写的要求
- 访问修饰符,返回值类型,方法名,参数列表全部一致
4 this和super 总结表格
5 有继承时创建对象的过程
- 先创建父类对象,再创建子类
- 类中是先属性初始化再执行构造
一、final
final是一个修饰符,用来修饰类,属性和方法的. 翻译: 最终
修饰类, final class
- 类不能被继承,其他正常使用
修饰变量/属性, final int a;
- 修饰属性/变量不再变化,
即变成常量,就得有初始值,且不能变化
修饰方法
- 方法不能被重写
二、static
2.1 介绍
static ,静态的,主要常用是用来修饰
- 属性
- 方法
static修饰的属性,方法也会,在内存的特性
- 加载时机: 随类加载而加载
- 初始化: 加载时就初始化
- 位置: 会随着加载出现在方法区中,不在堆中
static修饰的属性和方法,不在堆中,在方法区,且在**内存只有一个,**不管创建多少对象,该类静态属性和方法就只有一个,被该类的所有对象共享
static修饰的方法内,不能使用this
2.2 使用场景
场景1: 当想要某个数据被对象共享时,就定义该属性为static,例如 多个窗口对象共享火车票数据
场景2: static配合final,修饰属性(静态常量)
- fianl修饰后变常量
- static修饰后,可以通过类名直接调用
作用: 方便调用,不要创建对象就可以调用
场景3: static修饰方法,通过类名直接调用,方便
例如: Arrays,Math类中全部都是静态方法,可以通过类名直接调用
Arrays.toString()
Arrays.sort()
Math.pow();
2.3 使用总结
什么时候我们需要加static
- 当一些属性需要被共享时,给属性设置static
- 当某个方法想方便调用时,给方法设置static,可以同类名直接调用
- 经验: 测试类,工具类性质的方法可以设置static,其他实体类一般不加
有了static该怎么调用
- 静态只能调用静态
- 非静态可以调用非静态也可以调用静态
重写时,静态方法不能重写!!就算子父类一模一样的静态方法也不是重写!!
三、多态
3.1 多态介绍
多态,就是指方法多种状态,换句话说多态就是同一个方法会表现出不同的状态
- 举例: 豹女奈德丽的技能: 人形时qwe技能和豹形时qwe不一样
3.2 多态前提
要形成多态的这种效果,得满足以下三个条件
- 继承/实现(有子父类关系)
- 重写
- 父类引用指向子类对象(向上转型)
// 父类
public class Animal {
public void eat(){
System.out.println("动物吃" );
}
}
// 子类Dog
public class Dog extends Animal {// 多态条件1继承
// 多态条件2重写
@Override
public void eat() {
System.out.println("狗吃骨头" );
}
}
// 测试
public class TestPoly {
public static void main(String[] args) {
// 父类引用指向父类对象
// Animal animal = new Animal();
// 父类引用指向子类对象
Animal animal = new Dog();
animal.eat();// 编译看父类,运行看子类
// eat方法是子类在执行
}
}
3.3 多态什么作用?
多态好处: 减少耦合,提供扩展性
// 现在有需求,设计方法传入一个狗类,执行出狗吃东西
// 现在需求变了,想要表现出猫如何吃东西,该怎么办?
// 假如,要展现动物园所有动物如何吃呢? 再假如后续又来了以前没有的动物,该如何表现吃的行为呢? 简单粗暴的想法,多定义几个方法…
可以,但是很麻烦! 这些写,扩展性不好,来一个需要都需要改代码…
怎么办? 就需要多态!
只需要将方法的参数列表改变成父类即可,调用时传入想要表现的子类对象即可
3.4 多态使用注意事项
- 父类里面的方法子类没有重写的话,无法体现多态
- 子类里面有特有方法,向上转型后父类方法也无法调用
// 解释下面代码,给出运行结果
// 问:该程序是否能编译通过?如果可以,输出结果是什么?如果不可以,应该如 何修改?
class Super {
public void method() {
System.out.println("method() in Super");
}
public void method(int i) {
System.out.println("method(int) in Super");
}
}
class Sub extends Super {
public void method() {
System.out.println("method() in Sub");
}
public void method(String str) {
System.out.println("method(String) in Sub");
}
}
public class TestSuperSub {
public static void main(String args[]) {
Super s = new Sub( );
s.method(10);
s.method( );
s.method("hello");// 报错,为什么?
}
}
四、向上&向下转型
4.1 向上转型
向上转型: 父类引用指向子类对象 Animal a = new Dog();
将Dog类(子类)的对象,包装成Animal类(父类)类型的对象, 子类变父类,
也可以理解为类型转换: 小转大
为什么需要向上转型? 就是为了多态效果,方便写代码的
向上转型后需要注意
- 父类引用只能调用父类中有的方法(编译看父类)
- 真正执行时看子类
4.2 向下转型
什么是向下转型?
向上转型是子类对象变父类对象,那
向下转型就是 父类对象变子类对象,类似这样 Dog dog = new Animal();
但是这是类型转换中 “大转小” , 需要强制进行 Dog dog = **
(Dog)
**new Animal();这就是向下转型
需要注意,向下转型不一定成功! 想要成功先向上再向下
为什么需要向下转型?是因为向上转型后父类无法调用子类特有方法,所以需要再变为子类调用子类特有方法
五、多态的应用场景
方法参数列表是父类类型,调用方法传参数时,传入子类对象,运行时出现各自子类效果
方法返回值是父类类型
数组类型是父类类型,
- 比如形状数组,存储形状子类(圆形,矩形,正方形)
- 比如员工数组,存储员工子类(底薪员工,小时工,销售员工)
六、总结
关于final,重点是修饰变量为常量,不可改变这个点
关于static,重点是方便调用,类名可以直接调用属性和方法,然后属性是只有一个被共享!
关于多态,要记住
- 语法特征: 继承,重写,向上转型
- 代码效果: 编译看父类,运行看子类
- 向下转型是什么?怎么转不报错?
- 熟练使用场景即可