离开了家乡,开始我的流浪
身上只带着公仔,Qpee 和 Guitar
一、final 关键字
不可改变的,最终的。它可以修饰成员变量,成员方法,类
修饰类
该类不能被继承
修饰变量
成员变量成为常量,只能被赋值一次,不能被修改
修饰成员方法
方法不能被重写
1、final 修饰的是基本数据类型的变量,值不能被修改
2、修饰是引用数据类型的变量的时候,地址值不能被修改
3、final 修饰变量的初始化时机,在构造对象完毕之前即可
(构造方法、静态代码块、构造代码块内完成赋值均可)
二、多态 (polymorphic)
1、基本
多态:某一个事物,在不同时刻体现出来的不同的状态
多态的前提
1、继承
2、重写(否则多态无意义)
3、父类引用指向派生类对象
书写格式
父类 对象名 = new 派生类
2、多态访问成员特点
1、成员变量
编译看左边,运行看左边
2、构造方法
创建子类对象的时候,先访问父类的构造方法,先对父类的数据进行初始化
3、成员方法
编译看左边,运行看右边
若存在重写,则直接调用,若无,向父类继承的方法中寻找,再无则报错
4、静态的成员方法:
编译看左边,运行看左边
静态的随着类的加载而加载,所以两个重复的静态会同时存在,不属于重写
运行父类引用的 static 方法
总结:
只有访问成员方法的时候是编译看左边,运行看右边,其他的是编译看左边,运行看左边
3、向上转型和向下转型
向上转型
多态就是一个典型的向上转型,指向派生类的父类引用
父类 对象名 = new 派生类
可以看做是派生类的核心,外面套了一层父类的外壳
向下转型
将被父类引用的派生类重新用派生类引用接回
派生类 对象名= (派生类)父类
可以看做是将多态时套上的外壳剥下,重新套上新的外壳
内存图
3、instanceof 关键字
instanceof 是 Java 的一个关键字,左边对象,右边类,返回是Boolean类型
对象名 instanceof 类
它的具体作用是测试左边的对象是否是右边类或者该类的子类创建的实例对象,是,则返回 true,否则返回 false
4、多态访问成员特点
优点
提高了程序的维护性(由继承保证)
提高了程序的扩展性(由多态保证)
缺点
多态的弊端:
1、不能访问子类的特有功能
(由多态访问成员的特点导致的)
解决方式:
向下转型
格式:派生类 z = (派生类)父类
必须要存在继承关系,而且不能夸层转型
2、不能通过多态去访问父类和子类同名的方法
解决方式:
super 关键字,调用父类的成员
五、练习
// test1
class Animal{
public void eat(){
System.out.println("吃");
}
}
class Dog extends Animal{
public void eat(){
System.out.println("狗吃肉");
}
public void lookDoor(){
System.out.println("看门");
}
}
class Cat extends Animal{
public void eat(){
System.out.println("猫吃鱼");
}
public void catchMice(){
System.out.println("捉老鼠");
}
}
public class PolymorphicTest1 {
public static void main(String[] args) {
//使用多态定义一个狗
Animal3 a = new Dog3();
a.eat();
// a.lookDoor(); //报错
System.out.println("----------------");
//向下转型
Dog3 d = (Dog3)a;
d.eat();
d.lookDoor();
System.out.println("-------------");
//多态 向上转型
a = new Cat3();
a.eat();
// a.catchMice(); //报错
System.out.println("-------------");
//向下转型
Cat3 c = (Cat3)a;
c.eat();
c.catchMice();
//错误的演示
// Dog3 dd = new Animal3();
// Dog3 ddd = new Cat3();
// Dog3 dddd = (Dog3) a; //ClassCastException
/* test2
爷爷 --- 父亲 --- 儿子
*/
class GrandFather{
public void song(){
System.out.println("唱山歌");
}
}
class Father extends GrandFather{
public void song(){
System.out.println("唱情歌");
}
}
class Son extends Father{
public void song(){
System.out.println("唱儿歌");
}
}
public class PolymorphicTest12 {
public static void main(String[] args) {
//向上转型
GrandFather gf = new Father();
//向上转型
GrandFather gf1 = new Son();
//向下转型,可以看做是对gf1的重新向上转型
Father f = (Father) gf1;
// 向上转型
Father f1 = new Son();
//ClassCastException
//Son s = (Son)((Father)gf);
}
}
// test3
/*
不同地方饮食文化不同的案例
*/
class Person{
public void eat(){
System.out.println("吃饭");
}
}
class SouthPerson extends Person{
public void eat(){
System.out.println("炒菜,米饭");
}
public void playMahjong(){
System.out.println("打麻将");
}
}
public class PolymorphicTest3 {
public static void main(String[] args) {
//测试 //南方人
Person p1 = new SouthPerson();
p1.eat();
//使用匿名对象的方式调用
((SouthPerson) p1).playMahjong();
// p1.playMahjong();
/* test4
继承的时候:
子类中有和父类一样的方法的时候,叫重写,覆盖
子类中没有和父类一样的方法的时候,方法就被继承过来,
但是当子类重写了父方法,结果就是被重写的那个结果
*/
class A{
public void show(){
show2();
}
public void show2(){
System.out.println("这是show2方法");
}
}
class B extends A{
// 此处的方法写不写都一样,因为和继承来的相同
// public void show(){
// show2();
// }
public void show2(){
System.out.println("这是在B里面的show2方法");
}
}
class C extends B{
public void show(){
super.show();
}
public void show2(){
System.out.println("这是在C里面的show2方法");
}
}
public class PolymorphicTest4 {
public static void main(String[] args) {
A a = new B();
a.show(); //结果是B的show2
B b = new C();
b.show(); //结果是C的show2
}
}
总结
final 关键字
修饰类
该类不能被继承
修饰变量
成员变量成为常量,只能被赋值一次,不能被修改
修饰成员方法
方法不能被重写
多态
向上转型
多态就是一个典型的向上转型,指向派生类的父类引用
父类 对象名 = new 派生类
可以看做是派生类的核心,外面套了一层父类的外壳
向下转型
将被父类引用的派生类重新用派生类引用接回
派生类 对象名= (派生类)父类
可以看做是将多态时套上的外壳剥下,重新套上新的外壳