由浅到深认识Java语言(14):多态

该文章Github地址:https://github.com/AntonyCheng/java-notes【有条件的情况下推荐直接访问GitHub以获取最新的代码更新】

在此介绍一下作者开源的SpringBoot项目初始化模板(Github仓库地址:https://github.com/AntonyCheng/spring-boot-init-template【有条件的情况下推荐直接访问GitHub以获取最新的代码更新】& CSDN文章地址:https://blog.csdn.net/AntonyCheng/article/details/136555245),该模板集成了最常见的开发组件,同时基于修改配置文件实现组件的装载,除了这些,模板中还有非常丰富的整合示例,同时单体架构也非常适合SpringBoot框架入门,如果觉得有意义或者有帮助,欢迎Star & Issues & PR!

上一章:由浅到深认识Java语言(13):继承

23.多态(面向对象第三大特性)

概念

一种事物的多种状态,形态,多态能够帮助我们大大提高开发效率;

向上转型

  • 父类的引用指向子类对象的实体; <==> 也成为向上转型
  • 接口的引用指向接口实现的实体;
Student extends Person;
Student extends Animal;
Person p = new Student();
Animal a = new Student();

示例一:

父类有:

  • Person 类:

    package top.sharehome.BagOne;
    
    public class Person {
    	private String name;
    	private int age;
    	
    	public void dancing() {
    		System.out.println("跳舞");
    	}
    	
    	public String getName() {
    		return name;
    	}
    	public void setName(String name) {
    		this.name = name;
    	}
    	public int getAge() {
    		return age;
    	}
    	public void setAge(int age) {
    		this.age = age;
    	}
    	public Person() {
    		super();
    		// TODO Auto-generated constructor stub
    	}
    	public Person(String name, int age) {
    		super();
    		this.name = name;
    		this.age = age;
    	}
    }
    
  • Animal 类:

    package top.sharehome.BagOne;
    
    public class Animal {
    	private String name;
    	private int age;
    	public void dancing() {
    		System.out.println("跳舞");
    	}
    	public Animal(String name, int age) {
    		super();
    		this.name = name;
    		this.age = age;
    	}
    	public String getName() {
    		return name;
    	}
    	public void setName(String name) {
    		this.name = name;
    	}
    	public int getAge() {
    		return age;
    	}
    	public void setAge(int age) {
    		this.age = age;
    	}
    	public Animal() {
    		super();
    		// TODO Auto-generated constructor stub
    	}
    }
    

子类有:

  • Man 类:

    package top.sharehome.BagOne;
    
    public class Man extends Person{
    	@Override
    	public void dancing() {
    		System.out.println("男人跳拉丁舞");
    	}
    }
    
  • Woman 类:

    package top.sharehome.BagOne;
    
    public class Woman extends Person{
    	@Override
    	public void dancing() {
    		System.out.println("女人跳民族舞");
    	}
    }
    
  • Teacher 类:

    package top.sharehome.BagOne;
    
    public class Teacher extends Person {
    	@Override
    	public void dancing() {
    		System.out.println("老师跳恰恰舞");
    	}
    }
    
    
  • Dog 类:

    package top.sharehome.BagOne;
    
    public class Dog extends Animal{
    	@Override
    	public void dancing() {
    		System.out.println("边吃边跳");
    	}
    }
    

Demo 类可以这样写:

package top.sharehome.BagOne;

public class Demo {
	public static void main(String[] args) {
		Man m1 = new Man();
		Man m2 = new Man();
		Woman w1 = new Woman();
		Woman w2 = new Woman();
		Teacher t1 = new Teacher();
		Teacher t2 = new Teacher();
		Dog d = new Dog();
		coming(m1);
		coming(m2);
		coming(t1);
		coming(w2);
	}
	public static void coming(Man m) {
        m.dancing();
    }

    public static void coming(Teacher t) {
        t.dancing();
    }

    public static void coming(Woman w) {
        w.dancing();
    }
}

打印效果如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Demo 类也可以利用多态这样写:

package top.sharehome.BagOne;

public class Demo {
	public static void main(String[] args) {
		Man m1 = new Man();
		Man m2 = new Man();
		Woman w1 = new Woman();
		Woman w2 = new Woman();
		Teacher t1 = new Teacher();
		Teacher t2 = new Teacher();
		Dog d = new Dog();
		coming(m1);
		coming(m2);
		coming(t1);
		coming(w2);
		//coming(d); //这里会报错,因为父类不统一
	}
	public static void coming(Person p) { //用Person父类名去替换子类名
		p.dancing();
	}
}

打印效果如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

示例二:

Person 类:

package top.sharehome.BagOne;

public class Person {
	public void method() {
		System.out.println("人");
	}
}

Man 类:

package top.sharehome.BagOne;

public class Man extends Person{
	public void method() {
		System.out.println("男人");
	}
}

Woman 类:

package top.sharehome.BagOne;

public class Woman extends Person {
	public void method() {
		System.out.println("女人");
	}
}

Demo 类:

package top.sharehome.BagOne;

public class Demo {
	public static void main(String[] args) {
		Man m = new Man();
		Woman w = new Woman();
		coming(m);
		coming(w);
	}
	public static void coming(Person p) {  //这里可以用 Person 父类去向上转型
		p.method();
	}
}

打印效果如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

**注意:**多态的情况下,编译时是看父类的属性和方法,如果父类没有而子类有,则没法调用子类的属性和方法;运行时是看子类的属性和方法,如果子类和父类有相同元素,则运行时调用子类里的属性和方法;

编译时是看父类的属性和方法:

package top.sharehome.BagOne;

public class Demo {
	public static void main(String[] args) {
		Man m = new Man();
		Woman w = new Woman();
		coming(m);
		coming(w);
	}

	public static void coming(Person p) {
		p.method();
		p.method1();  //这里会报错,因为 Person 父类里没有 method1 这个方法;
        			  //即使 Man 子类里有,仍然不能调用;
	}
}

class Person {
	public void method() {
		System.out.println("Person.method");
	}
}

class Man extends Person {
	public void method() {
		System.out.println("Man.method");
	}

	public void method1() {
		System.out.println("Man.method1");
	}
}

class Woman extends Person {
	public void method() {
		System.out.println("Woman.method");
	}
}

运行时是看子类的属性和方法:

package top.sharehome.BagOne;

public class Demo {
	public static void main(String[] args) {
		Person p1 = new Man();
		Person p2 = new Woman();
		coming(p1);
		coming(p2);
	}

	public static void coming(Person p) {
		p.method();
		p.method1();
	}
}

class Person {
	public void method() {
		System.out.println("Person.method");
	}
	public void method1() {
		System.out.println("Person.method1");
	}
}

class Man extends Person {
	public void method() {
		System.out.println("Man.method");
	}

	public void method1() {
		System.out.println("Man.method1");
	}
}

class Woman extends Person {
	public void method() {
		System.out.println("Woman.method");
	}
}

打印效果如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

向下转型

如果父类中没有元素和方法,而子类中有元素和方法,我们想要通过多态来调用子类中父类没有的那个元素,就需要向下转型,方法和数据结构的强制转换相类似,例如:

package top.sharehome.BagOne;

public class Demo {
	public static void main(String[] args) {
		Person p1 = new Man();
		Man m = (Man)p1;
		m.method1();
	}
}

class Person {  //父类中没有 method1 这个方法
	public void method() {
		System.out.println("Person.method");
	}
}

class Man extends Person {
	public void method() {
		System.out.println("Man.method");
	}

	public void method1() {
		System.out.println("Man.method1");
	}
}

打印效果如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

instanceof关键字

作用:

instanceof 关键字用来识别子类之间的元素关系,判断对象是否属于该类;

在多态的向下转型中,确保对象属于该类,保证了向下转型的安全性;

基本格式:

对象名 instance 类名    <==>   结果是一个Boolean值,对象名属于类名则为ture;

示例如下:

package top.sharehome.BagOne;

public class Demo {
	public static void main(String[] args) {
		Person p1 = new Man();
		Person p2 = new Woman();
		show(p1);  //
		show(p2);  
	}

	public static void show(Person p) {
		if (p instanceof Woman) {
			Woman w = (Woman) p;
			w.method();
		}
	}
}

class Person {
	public void method() {
		System.out.println("Person.method");
	}
}

class Man extends Person {
	public void method() {
		System.out.println("Man.method");
	}
}

class Woman extends Person {
	public void method() {
		System.out.println("Moman.method");
	}
}

打印效果如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

下一章:由浅到深认识Java语言(15):final关键字&抽象类

  • 14
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值