多态
多态的描述
现实理解就是:一个事物的多种形态,例如:水,有固态,液态,气态,三种形式
程序中:开辟一个子类空间,通过父类对象存储,然后调用里面的成员变量和成员方法,会有不同的表现形式
多态的具体写法
格式:
父类名 对象名 = new 子类名();
父类接口名 对象名 = new 子类名();
多态中成员的访问
demo:通过父类对象引用子类空间,访问成员变量和成员方法时,输出的到底是啥?
定义一个名字为Animal的父类
/**
* @Classname : Animal
* @Description : TODO 动物类
* @Author : lin_refuel@qq.com
*/
public class Animal {
//定义一个成员属性
public String name = "动物";
//定义一个成员方法
public void eat(){
System.out.println(this.name + "基本功能是会吃");
}
}
定义一个名字为Cat的子类,继承上面的Animal类
/**
* @Classname : Cat
* @Description : TODO 猫类
* @Author : lin_refuel@qq.com
*/
public class Cat extends Animal{
//定义一个和父类相同名字的成员属性name
public String name = "猫"; //名字
//定义一个Cat类中自己的属性
public String age = "15岁";//年龄
//重写Animal类里的eat方法
@Override
public void eat() {
System.out.println(this.name + "会吃鱼");
}
//定义一个猫类的特有的方法
public void action(){
System.out.println(this.name + "会爬树");
}
}
测试,父类引用子类空间的时访问成员输出什么
/**
* @Classname : test
* @Description : TODO 测试类
* @Author : lin_refuel@qq.com
*/
public class test {
public static void main(String[] args) {
//通过父类Animal来引用子类Cat里面的空间时,这个可以理解为多态
Animal animal = new Cat();
//通过,父类对象animal访问成员变量时
//编译器根据等号左边的类型进行界定,编译看左,运行看左
//System.out.println(animal.maxAge);Animal无法访问子类里面的成员变量maxAge
System.out.println(animal.name);//Animal可以访问自己类中的成员属性
//总之记住,父类对象引用子类空间时,父类对象访问成员变量,访问的是父类空间的属性
System.out.println("============================");
//通过父类animal引用子类的空间时,访问里面的成员方法
//记住编译看左,运行成员方法时看右边
//animal.action,父类对象没有办法访问子类里面特有的成员方法
animal.eat();//但是父类可以访问子类里面重写后的成员方法
//总之记住,父类对象引用子类空间时候,父类对象访问的成员方法,只能是子类重写的和父类中相同的成员方法
}
}
运行结果:
向上和向下转型
向上转换,通过父类对象引用子类空间
向下转换,父类对象转换成new 的子类空间的类型
demo
定义一个Animal类
package com.itxs.demo01;
/**
* @Classname : Animal
* @Description : TODO 动物类 - 父类
* @Author : lin_refuel@qq.com
*/
public class Animal {
public String name = "动物";
//定义一个eat方法
public void eat(){
System.out.println(this.name + "基本功能是吃");
}
}
定义一个Cat类,继承上面的动物类
package com.itxs.demo01;
/**
* @Classname : Cat
* @Description : TODO 猫类 - 继承Animal类
* @Author : lin_refuel@qq.com
*/
public class Cat extends Animal{
public String name = "猫";
public String age = "15岁";
//重写Animal类里面的eat方法
@Override
public void eat() {
System.out.println(this.name + "会吃鱼");
}
//定义一个方法,猫的运动方式
public void sport(){
System.out.println(this.name + "会上树");
}
}
定义一个Dog类,继承上面的Animal类
package com.itxs.demo01;
/**
* @Classname : Dog
* @Description : TODO 狗类 - 继承Animal类
* @Author : lin_refuel@qq.com
*/
public class Dog extends Animal{
//定义一个和猫类同名的方法sport
public void sport(){
System.out.println("狗会游泳");
}
}
测试类
package com.itxs.demo01;
/**
* @Classname : demoTest
* @Description : TODO 测试类
* @Author : lin_refuel@qq.com
*/
public class demoTest {
public static void main(String[] args) {
//向上转型,父类对象引用子类空间
Animal animal = new Cat();
//访问成员变量
System.out.println(animal.name);
//访问成员方法
animal.eat();
//向上转型无法访问子类成员特有方法
System.out.println("==========================");
//向下转型,父类转换成子类
//父类只能转换成引用的子类空间的类型
//例如:animal是父类,转换成Cat类
//一般搭配if(父类实例化对象名字 instanceof 子类名字)进行判断,格式如下
if(animal instanceof Cat)//Animal是否可以转换成Cat类
// 转化方式:((子类名字)父类实例化对象名字)
((Cat)animal).sport(); //访问成员方法
//父类没有引用子类,不能进行强制转
if(animal instanceof Dog) //判断animal对象是否可以转换成为Dog类
((Dog)animal).sport();
}
}
运行结果:
父类无法随意转换,只能转换成引用过的子类,所以Dog类里面成员方法没有输出
多态小案例–USB设备
鼠标键盘计算机之间的连接
1.定义一个名字为USB的抽象类,里面设置usb设备的功能,开和关
package com.itxs.demo02;
/**
* @Classname : USB
* @Description : TODO 定义一个USB抽象类
* @Author : lin_refuel@qq.com
*/
public abstract class USB {
//定义两个抽象方法,作为每个USB设备都有的功能
abstract void open();//开
abstract void close();//关
}
2.定义两个子类,Mouse类和Keyboard类,继承上面的USB类
2.1 Mouse类
package com.itxs.demo02;
/**
* @Classname : Mouse
* @Description : TODO 鼠标类 - 继承USB类
* @Author : lin_refuel@qq.com
*/
public class Mouse extends USB{
//重写USB类中的两个功能,
@Override
public void open() {
System.out.println("鼠标插入computer --- 插入成功");
}
@Override
public void close() {
System.out.println("鼠标被拔出 ----- 鼠标被移除");
}
//定义出几个鼠标的操作
// 双击
public void doubleClick(){
System.out.println("鼠标双击浏览器");
}
//鼠标左键被点击
public void leftClick(){
System.out.println("鼠标左边点击csdn网址");
}
//鼠标右键点击
public void rightClick(){
System.out.println("鼠标右键点击一个图片,进入详情");
}
}
2.2 Keyboard类
package com.itxs.demo02;
/**
* @Classname : Keyboard
* @Description : TODO 键盘类 - 继承 USB抽象类
* @Author : lin_refuel@qq.com
*/
public class Keyboard extends USB{
//重写USB里面的两个功能
@Override
void open() {
System.out.println("键盘已经被插入Computer-----键盘插入成功");
}
@Override
void close() {
System.out.println("键盘已经拔出-----移除键盘");
}
public void input(){
System.out.println("键盘输入csdn,搜索尾音TuT");
}
}
3.定义一个名字为Computer类,继承USB类,该类实现键盘和鼠标插入后调用里面的成员方法
package com.itxs.demo02;
/**
* @Classname : Computer
* @Description : TODO 计算机类
* @Author : lin_refuel@qq.com
*/
public class Computer extends USB {
@Override
void open() {
System.out.println("计算机已经被打开");
}
@Override
void close() {
System.out.println("计算机已经被关闭");
}
/**
* 存储不同对象空间,调用里面的非USB类的方法
* @param dev 存储Mouse类或者Keyboard类空间
* 例如: USB dev = new Mouse,通过父类引用子类空间进行调用
*/
public void insert(USB dev){
//判断USB类转换到Mouse类
if(dev instanceof Mouse){
((Mouse)dev).doubleClick();
((Mouse)dev).leftClick();
((Mouse)dev).rightClick();
//判断,USB类是否转换到Keyboard类
}else if(dev instanceof Keyboard){
((Keyboard)dev).open();
((Keyboard)dev).input();
((Keyboard)dev).close();
}else{
System.out.println("非法设备");
}
}
}
4.定义一个测试类
package com.itxs.demo02;
/**
* @Classname : test
* @Description : TODO 测试类
* @Author : lin_refuel@qq.com
*/
public class test {
public static void main(String[] args) {
Computer computer = new Computer();//创建一个电脑对象
computer.open();//调用computer里面的方法
computer.insert(new Mouse());
System.out.println("=================");
computer.insert(new Keyboard());
computer.close();
}
}
运行结果: