Java多态性
Java多态性
面向对象三大特征:封装性,继承性,多态性.
extends继承或者implements实现,是多态的前提
一个对象拥有多种形态这就是:对象的多态性
多态的实现
代码中体现多态性:父类引用指向子类对象
格式
父类名称 对象名 = new 子类名称();
或者
接口名称 对象名 = new 实现类名称();
代码示例
Fu类
public class Fu {
public void method() {
System.out.println("父类成员方法");
}
public void methodFu() {
System.out.println("我是父类独有的成员方法");
}
}
Zi类
public class Zi extends Fu {
public void method()
{
System.out.println("子类成员方法");
}
}
Main方法
public class Multi {
public static void main(String[] args) {
//使用多态的写法
//左侧父类引用,指向了右侧的子类对象
Fu one = new Zi();//
one.method();//还是优先使用子类方法,new的谁将优先使用谁
one.methodFu();//如果子类没有会向上寻找父类方法
}
}
多态中成员变量的访问特点
访问成员变量的两种方式
- 直接通过对象名称访问成员变量,看等号左边是谁,优先用谁,没有,则向上找.
- 间接通过成员方法访问成员变量:看该方法属于谁,优先用谁,没有则向上找.
Fu类
public class Fu {
int num=10;
public void show()
{
System.out.println(num);
}
}
public class Fu {
int num=10;
public void show()
{
System.out.println(num);
}
}
Zi类
public class Zi extends Fu{
int num =20;
int age=20;
public void show()
{
System.out.println(num);
}
}
Main方法
public class Main {
public static void main(String[] args) {
Fu one = new Zi();//多态写法
System.out.println(one.num);//父类 10;
// System.out.println(one.age);子类当中才有age错误写法
System.out.println("=========");
//如果子类没有覆盖重写,就是父:10;
//如果子类覆盖重写之后就是子:20;
one.show();
}
}
多态中成员方法的使用特点
在多态代码中,成员方法的访问规则是:
看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 void methodZi()
{
System.out.println("子类独有方法");
}
}
main方法
public class Main {
public static void main(String[] args) {
Fu one = new Zi();
one.method();//父子都有优先用子
one.methodFu();//子类没有,父类有,优先用父类
// one.methodZi();错误写法
//编译看左边,Fu类没有该方法编译报错,不能这样写
}
}
使用多态的好处
无论右边new的时候换成哪个子类对象,等号左边调用方法都不会变化.
对象的向上转型
对象的向上转型,就是多态写法:
格式:父类名称 对象名 = new 子类名称();
含义:右侧创建一个对象,把它当作父类来看待使用
注意:向上转型一定是安全的,范围从大变小
代码示例
父类
public abstract class Animal {
public abstract void eat();
}
子类
public class Cat extends Animal{
@Override
public void eat() {
System.out.println("猫喜欢吃鱼");
}
}
Main方法
public class Main {
public static void main(String[] args) {
Animal one = new Cat();
//对象向上转型,就是,父类对象引用指向子类对象
one.eat();//运行看左,编译看右
}
}
对象的向下转型
向上转型一定是安全的,没有问题的,正确的,但是也有一个弊端.
对象一旦向上转型为父类,那么就无法调用子类原本的内容.
解决方法,用对象的向下转型[还原]
对象的向下转型是一个[还原]的动作
格式:子类名称 对象名 =(子类名称) 父类对象
含义:将父类对象,[还原]成为本来的子类对象
注意:
必须保证对象创建的时候就是猫,才能向下转型成为猫.
Animal类
public abstract class Animal {
public abstract void eat();
}
Cat类
public class Cat extends Animal{
@Override
public void eat() {
System.out.println("猫喜欢吃鱼");
}
public void catch_mouse()
{
System.out.println("猫抓老鼠");
}
}
Dog类
public class Dog extends Animal{
@Override
public void eat() {
System.out.println("狗吃骨头");
}
public void look()
{
System.out.println("狗看家");
}
}
Main类
public class Main {
public static void main(String[] args) {
Animal one = new Cat();
//对象向上转型,就是,父类对象引用指向子类对象
one.eat();//运行看左,编译看右
// one.catch_mouse();//错误写法
//向下转型,进行"还原动作"
Cat two = (Cat)one;//像下转型,将动物转换为了猫
two.catch_mouse();//可以使用Cat的成员变量
two.eat();
Dog three =(Dog) one;//编译正常运行出错,猫不能变成狗
}
}
instanceof关键字
如何才能知道一个父类引用的对象本来是什么子类?
格式:
对象 instandof 类名称
这将会得到一个boolean值
代码示例
动物类
public class Animal {
public void eat()
{
System.out.println("动物要吃东西");
}
}
Dog类
public class Dog extends Animal{
@Override
public void eat() {
System.out.println("狗吃骨头");
}
public void look()
{
System.out.println("狗看家");
}
}
Cat类
public class Cat extends Animal{
@Override
public void eat() {
System.out.println("猫喜欢吃鱼");
}
public void catch_mouse()
{
System.out.println("猫抓老鼠");
}
}
Main方法
public class Main {
public static void main(String[] args) {
Animal one = new Dog();
if (one instanceof Cat)//使用instandof进行判断
{
Cat two = (Cat) one;//向下转型
two.eat();
two.catch_mouse();
}
if (one instanceof Dog)//使用instandof进行判断
{
Dog two = (Dog) one;
two.eat();
two.look();
}
gevMeAPat(new Cat());//传入一个人dog
}
public static void gevMeAPat(Animal three)//需要一个animal
//下面进行判断
{
if (three instanceof Cat)//使用instandof进行判断
{
Cat two = (Cat) three;//向下转型
two.eat();
two.catch_mouse();
}
if (three instanceof Dog)//使用instandof进行判断
{
Dog two = (Dog) three;
two.eat();
two.look();
}
}
}