对象的向上转型
1.对象的向上转型。其实就是多态写法:
格式:父类名称 对象名 = new 子类名称(); Animal animal = new Cat();
含义:右侧创建—个子类对象,把它当做父类来看待使用。 创建了一只猫,当做动物看待,没问题。
注意事项:向上转型一定是安全的。从小范围转向了大范围,从小范围的猫,向上转换成为更大范围的动物。
类似于:
double num = 100; //正确,int --> double,自动类型转换。
对象的向下转型
2.对象的向下转型,其实是一个【还原】的动作。
格式:子类名称 对象名 =(子类名称) 父类对象; Cat cat = (Cat) animal;
含义:将父类对象,【还原】成为本来的子类对象。 本来是猫,已经被当做动物了,还原回来成为本来的猫
注意事项:
a.必须保证对象本来创建的时候,就是猫,才能向下转型成为猫。
b.如果对象创建的时候本来不是猫,现在非要向下转型成为猫。就会报错。
类似于:
int num =(int)10.0;//可以 int num =(int)10.5//精度损失
public abstract class Animal { public abstract void eat(); } ============================================== public class Cat extends Animal{ @Override public void eat() { System.out.println("猫吃鱼"); } public void catchMouser(){ System.out.println("猫抓老鼠"); } } =============================================== public class Demo01Man { public static void main(String[] args) { //对象的向上转型,就是:父类引用指向之类对象 Animal animal = new Cat(); animal.eat();//猫吃鱼 //animal.catchMouser(); 错误写法! //向下转行,进行“还原”动作 Cat cat = (Cat) animal; cat.catchMouser();//猫抓老鼠 //下面是错误的向下转型 //本来new的时候是一只猫,现在非要当中狗 //错误写法!编译不会报错,但是运行会出现异常, // java.lang.ClassCastException 类转换异常 Dog dog = (Dog) animal; } } ================================================= public class Dog extends Animal{ @Override public void eat() { System.out.println("狗吃骨头"); } public void watchHouse(){ System.out.println("狗看家"); } }
用instanceof关键字进行判断
public class Demo01Instanceof { public static void main(String[] args) { Animal animal = new Cat();//本来是一只猫 animal.eat();//猫吃鱼 //如果希望调用子类特有方法,需要向下转型 //判断一下父类引用animal本来是不是Dog if(animal instanceof Dog){ Dog dog = (Dog) animal; dog.watchHouse(); } //判断一下父类引用animal本来是不是Cat if(animal instanceof Cat){ Cat cat = (Cat) animal; cat.catchMouser(); } Dexter(new Dog()); } public static void Dexter(Animal animal){ if(animal instanceof Dog){ Dog dog = (Dog) animal; dog.watchHouse(); } //判断一下父类引用animal本来是不是Cat if(animal instanceof Cat){ Cat cat = (Cat) animal; cat.catchMouser(); } } } 猫吃鱼 猫抓老鼠 狗看家
接口多态的综合案例USB
public interface USB { public abstract void open();//打开设备 public abstract void close();//关闭设备 }
public class Computer { public void powerOn(){ System.out.println("笔记本电脑开机"); } public void powerOff(){ System.out.println("笔记本电脑关机"); } //使用USB设备的方法,使用接口作为方法的参数 public void userDevice(USB usb){ usb.open(); if(usb instanceof Mouse){//先判断 Mouse mouse = (Mouse) usb;//向下转型 mouse.click(); }else if(usb instanceof Keyboard){//先判断 Keyboard keyboard = (Keyboard) usb;//向下转型 keyboard.type(); } usb.close(); } }
public class Mouse implements USB{ @Override public void open() { System.out.println("打开鼠标"); } @Override public void close() { System.out.println("关闭鼠标"); } public void click(){ System.out.println("鼠标点击"); } } public class Keyboard implements USB{ @Override public void open() { System.out.println("打开键盘"); } @Override public void close() { System.out.println("关闭键盘"); } public void type(){ System.out.println("键盘输入"); } }
public class DemoMain { public static void main(String[] args) { //首先创建一个笔记本电脑 Computer computer = new Computer(); computer.powerOn(); //首先进行向上转型 USB usbMouse = new Mouse();//多态写法 //参数是USB类型,传递进去的就是USB鼠标 computer.userDevice(usbMouse); //首先创建一个USB键盘 Keyboard keyboard = new Keyboard();//没有使用多态写法 //参数是USB类型,传递进去的是实现类对象 computer.userDevice(keyboard);//正确写法,也是向上转型 computer.userDevice(new Keyboard());//也是正确写法 computer.powerOff(); } }
final 关键字
final关键字代表最终、不可改变的。
常见四种用法:
1.可以用来修饰一个类
2.可以用来修饰一个方法
3中还可以用来修饰一个局部变量
4.还可以用来修饰─个成员变量
final 关键字用来修饰一个类
格式:
public final class 类名称 { //....... }
含义:当前这个类不能有任何的子类。
注意:一个类如果是final的,那么其中所有的成员方法都无法进行覆盖重写(因为没子类)
final 关键字用来修饰成员方法
当于final关键字用来修饰一个方法的时候,这个方法就是最终方法,也就是不能被覆盖重写。
格式:
修饰符 final 返回值类型 方法名称(参数列表) { //方法体 }
注意事项:
对于类、方法来说, abstract关键字和final关键字不能同时使用,因为矛盾。
public abstract final void method(); //错误写法 abstract 就是要被覆盖重写 而fianl就是不能被覆盖重写
final 关键字用来修饰局部变量
对于基本类型来说,不可变说的是变量当中的数据不可改变
—旦使用finaL用来修饰局部变量,那么这个变量就不能进行更改。 “一次赋值,终生不变” final int num1 = 200; System.out.println(num1);//200 num1 = 250;//错误写法 num1 = 200; //错误写法
对于引用类型来说,不可变说的是变量当中的地址值不可改变
final Student stu1 = new Student("张艺兴") //错误写法 fianl的引用类型变量,其中的地址不可改变 //stu1 = new Student("张子枫"); System.out.println(stu1.getname());//张艺兴 stu1.setName("张子枫"); System.out.println(stu1.getname());//张子枫
final 关键字用来修饰成员变量
对于成员变量来说,如果使用final关键字修饰,那么这个变量也照样是不可变。
1.由于成员变量具有默认值,所以用了final之后必须手动赋值,不会再给默认值了。
2.对于final的成员变量,要么使用直接赋值,要么通过构造方法赋值。二者选其一。
3.必须保证类当中所有重载的构造方法,都最终会对于final的成员变量进行赋值。