面向对象三大概述: 封装性、继承性、多态性
extends继承或者implements实现,是多态的前提
1.多态的格式和使用
/**
* 代码当中体现多态性,其实就是一句话,父类引用指向子类对象
* 格式:
* 父类名称 对象名 = new 子类名称();
* 或者:
* 接口名称 对象名 = new 实现类名称();
*/
案例:
public class Fu {
public void method(){
System.out.println("父类方法");
}
public void methodFu(){
System.out.println("父类特有");
}
}
public class Zi extends Fu{
@Override
public void method() {
System.out.println("子类方法");
}
}
public class Demo01Multi {
public static void main(String[] args) {
Fu obj = new Zi();
obj.method();
obj.methodFu();
}
}
2.多态中成员变量的使用特点
访问成员变量的方式:
1.直接通过对象名称访问成员变量,看等号左边是谁,优先用谁,没有则向上找
2.间接通过成员方法访问成员变量,看方法属于谁,优先用谁,没有则向上找
案例:
public class Demo01MultiField {
public static void main(String[] args) {
Fu obj = new Zi();
System.out.println(obj.num); //10;
//System.out.println(obj.age); //错误写法
System.out.println("========");
//子类没有覆盖重写,就是父,10
//子类如果覆盖重写,就是子,20
obj.showNum();
}
}
public class Zi extends Fu{
int num = 20;
int age = 16;
@Override
public void showNum(){
System.out.println(num);
}
}
public class Fu {
int num = 10;
public void showNum(){
System.out.println(num);
}
}
3.多态中成员方法的使用特点
在多态代码中,成员方法的访问规则是:
看new 的是谁,就使用谁,没有则向上找
成员变量:编译运行看左
成员方法:编译看左边,运行看右边
案例:
public class Demo02MultiMethod {
public static void main(String[] args) {
Fu obj = new Zi();//多态
obj.method();//父子都有,优先用子
obj.methodFu();//子类没有,父类有,向上找到父类
//obj.methodZi();//错误写法
}
}
public class Zi extends Fu{
int num = 20;
int age = 16;
@Override
public void showNum(){
System.out.println(num);
}
@Override
public void method(){
System.out.println("子类方法");
}
public void methodZi(){
System.out.println("子类特有");
}
}
public class Fu {
int num = 10;
public void showNum(){
System.out.println(num);
}
public void method(){
System.out.println("父类方法");
}
public void methodFu(){
System.out.println("父类特有");
}
}
4.对象的向上转型
对象的向上转型:(其实就是多态的写法)
格式:
父类名称 对象名 = new 子类名称();
含义:左侧创建一个子类对象,把它当做父类来看待和使用。
注意事项: 向上转型一定是安全的,从小范围转向大范围。
案例:
public abstract class Animal {
public abstract void eat();
}
public class Cat extends Animal{
@Override
public void eat() {
System.out.println("猫吃鱼");
}
}
public class Demo01Main {
public static void main(String[] args) {
Animal animal = new Cat();
animal.eat();
}
}
5.对象的向下转型
对象的向下转型,其实是一个还原的动作.
格式:
子类名称 对象名 = (子类对象)父类对象
含义:将父类对象,还原成本来的子类对象
案例:
public abstract class Animal {
public abstract void eat();
}
public class Cat extends Animal{
@Override
public void eat() {
System.out.println("猫吃鱼");
}
public void catchMouse(){
System.out.println("猫抓老鼠");
}
}
public class Dog extends Animal{
@Override
public void eat(){
System.out.println("狗吃shit");
}
public void watchHouse(){
System.out.println("狗看家");
}
}
public class Demo01Main {
public static void main(String[] args) {
Animal animal = new Cat();
animal.eat();
//animal.catchMouse();
Cat cat = (Cat) animal;
cat.catchMouse();
//错误的向下转型---java.lang.ClassCastException类装换异常
//Dog dog = (Dog) animal;
}
}
public class Demo01Main {
public static void main(String[] args) {
Animal animal = new Cat();
animal.eat();
//animal.catchMouse();
Cat cat = (Cat) animal;
cat.catchMouse();
//错误的向下转型---java.lang.ClassCastException类装换异常
//Dog dog = (Dog) animal;
}
}
6.用instanceof关键字进行类型判断
如何才能知道一个父类引用的对象,本来是什么子类?
格式
对象 instanceof 类名称
这将会得到一个boolean值的结果,也就是判断前面对象能不能当成后面类型的实例
案例:
public abstract class Animal {
public abstract void eat();
}
public class Cat extends Animal{
@Override
public void eat() {
System.out.println("猫吃鱼");
}
public void catchMouse(){
System.out.println("猫抓老鼠");
}
}
public class Dog extends Animal{
@Override
public void eat(){
System.out.println("狗吃shit");
}
public void watchHouse(){
System.out.println("狗看家");
}
}
public class Demo01Main {
public static void main(String[] args) {
Animal animal = new Cat();
animal.eat();
//animal.catchMouse();
// Cat cat = (Cat) animal;
// cat.catchMouse();
//错误的向下转型---java.lang.ClassCastException类装换异常
//Dog dog = (Dog) animal;
if(animal instanceof Dog){
Dog dog = (Dog) animal;
dog.watchHouse();
}
if(animal instanceof Cat){
Cat cat = (Cat) animal;
cat.catchMouse();
}
giveMeAnimal(new Dog());
}
public static void giveMeAnimal(Animal animal){
if(animal instanceof Dog){
Dog dog = (Dog) animal;
dog.watchHouse();
}
if(animal instanceof Cat){
Cat cat = (Cat) animal;
cat.catchMouse();
}
}
}
7.多态练习
public interface USB {
public abstract void open(); //打开设备
public abstract void 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 Computer {
public void powerOn(){
System.out.println("笔记本电脑开机");
}
public void powerOff(){
System.out.println("笔记本电脑关机");
}
public void useDevice(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 DemoMain {
public static void main(String[] args) {
Computer computer = new Computer();
computer.powerOn();
USB mouse = new Mouse();
computer.useDevice(mouse);
Keyboard keyboard = new Keyboard();
computer.useDevice(keyboard);//正确写法
computer.powerOff();
}
}