Java多态
多态的概念:
允许不同类的对象对同一消息作出不同响应。
编译时多态:设计时多态(方法重载)
运行时多态:程序运行时动态决定调用哪个方法。
必要的条件:
满足继承的关系
父类引用指向子类对象
实例代码:
父类:(动物类)
package cn.lqandzy.bean;
/**
- @author : 慕祈
- @date 创建时间:2018年2月12日 下午12:37:05
- @version 1.0
- @parameter
- @since
-
@return
*/
public class Animal {
private String name;
private int month;public int getMonth() {
return month;
}
public void setMonth(int month) {
this.month = month;
}
public void eat(){
System.out.println("吃东西");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}public Animal() {
System.out.println("我是父类的无参构造方法");
}
public Animal(String name, int month) {
super();
this.name = name;
this.month = month;
}
}
子类(猫)
package cn.lqandzy.bean;
/**
- @author : 慕祈
- @date 创建时间:2018年2月7日 下午1:44:11
- @version 1.0
- @parameter
- @since
-
@return
*/
public class Cat extends Animal{
private String weight;public Cat() {
System.out.println("我是子类的无参构造方法");
}public Cat(String name,int month,String weight) {
super(name,month);
setWeight(weight);
}public String getWeight() {
return weight;
}
public void setWeight(String weight) {
this.weight = weight;
}@Override
public void eat() {
System.out.println("猫吃鱼");
}@Override
public int getMonth() {
System.out.println("猫的年龄");
return this.getMonth();
}public void run(){
System.out.println("猫跑步");
}
}
子类(狗):
package cn.lqandzy.bean;
/**
- @author : 慕祈
- @date 创建时间:2018年2月12日 下午1:05:21
- @version 1.0
- @parameter
- @since
-
@return
*/
public class Dog extends Animal {
private int sex;public int getSex() {
return sex;
}
public void setSex(int sex) {
this.sex = sex;
}
public Dog(String name, int month, int sex) {
super(name, month);
setSex(sex);
}
public Dog() {
super();
}public void sleep(){
System.out.println("狗睡觉");
}
@Override
public void eat() {
System.out.println("狗吃肉");
}
@Override
public int getMonth() {
System.out.println("猫的年龄");
return this.getMonth();
}
}
向上转型:
父类引用指向子类实例
public static void main(String[] args) {
Animal animal=new Animal();
//向上转型
Animal animal1=new Cat();
Animal animal2=new Dog();
animal.eat();
animal1.eat();
animal2.eat();
animal.getMonth();
animal1.getMonth();
animal2.getMonth();
}
向下转型:
Cat cat=(Cat) animal1;
Dog dog=(Dog) animal2;
cat.eat();
dog.eat();
animal1原本就是cat的实例,所以强转不会报错。若对象的实例不想听,仍强转,就会出现类型转换错误。
InstanceOf:
我们可以借助这个关键字来判断对象是否是某一个类的实例。
System.out.println(animal1 instanceof Cat);
返回结果为true,说明animal1这个对象是cat这个类的实例。
此关键字可以加强强转的安全性
静态方法不能比子类重写
public static void say(){
System.out.println("说");
}
案例:
主人类:(根据喂养不同宠物做不同的动作。)
public class Master {
/* 喂宠物
- 如果是猫:完球
- 如果是狗:睡觉
*/
public void feed(Animal animal){
if(animal instanceof Cat){
System.out.println("玩球");
}
if(animal instanceof Dog){
System.out.println("睡觉");
}
}
}
测试类:
可以看到测试类feed中,穿进去的cat与dog实例进行的向上转型,在feed里进行判断实例为何,然后进行方法的逻辑调用。
这样的好处是,如果之后宠物有多少种,我只要一个方法就可以满足需求。
抽象类:
以下代码在编译上没有问题,但在程序逻辑上没有真正意义。
Animal animal=new Animal("花花",1);
animal.eat();
因为每一种动物都有吃的行为,但是这个实例没有指向任何一种动物,也就不存在任何意义,那么,有什么方法能提醒别人在写程序时不写这种编译没问题,但没有实际意义的代码呢。那就是抽象类。
我们在animal上加上abstract关键字
public abstract class Animal {
这样这个类就变成了抽象类。抽象类无法进行实例化
但是可以通过向上转型使用抽象类。
抽象方法:
不允许包含方法体,子类必须重写抽象方法。否则,子类也要是抽象类
public abstract void eat();
如果想在一个类中支持多种类型(继承只能继承一个),那么就需要使用接口。
抽象方法与常量
接口中的默认方法与静态方法
类实现接口后默认方法与静态可以不实现
如果接口中的有变量x,父类也有变量x,子类必须重写x,否则无法知道调用哪个x,从而报错。
如果是父类与接口都包含同名方法,优先使用父类的方法。
关于1.8接口的知识,可以参考这个传送门:
http://blog.csdn.net/aitangyong/article/details/54134385
接口的继承:
接口的继承比较特殊,可以实现多继承。
引用文字