1.Java中的多态
java有三大特性:封装,继承,多态
多态:即多种形态。是面向对象的三大特性之一。多态建立在封装和继承之上。
1.1方法的多态
方法的重写和重载就是方法的多态的体现形式。
1.2对象的多态
1.2.1一些概念
1.一个对象的编译类型和运行类型是不一样的。编译类型是在定义对象时就已经确定好的,运行类型则是可以改变的。编译类型看创建对象等号的左边,运行类型看创建对象等号的右边。
2.对象的多态:父类的引用指向子类的对象。
如 Animal animal1 = new Dog();
等号左边是父类的引用,等号右边是子类的对象。
代码示例:
class Animal {
public void eat() {
System.out.println("饿饿,饭饭");
}
}
class Dog extends Animal {
//重写父类的方法
@Override
public void eat() {
System.out.println("狗吃骨头");
}
//子类独有的方法
public void shout() {
System.out.println("汪汪汪!!!");
}
}
public class Demo1 {
public static void main(String[] args) {
//多态:父类的引用指向子类的对象
Animal animal = new Dog();
//可以指向子类中重写父类的方法
animal.eat(); //狗吃骨头
//不能指向子类中独有的方法
//animal.shout(); //报错
}
}
1.2.2注意事项
1.必须要有继承(或实现)关系,以及方法的重写。
2.父类的引用可以指向子类中重写的父类的方法,但是指向不了子类独有的方法。
1.3多态的转型
1.3.1多态的向上转型(子类转父类)
本质:父类的引用指向子类的对象
语法格式: 父类 父类引用 = new 子类();
将子类的对象赋值给了父类的引用。小范围转大范围,自动转换。
父类的引用调用父类的所有的成员方法,但是不能调用子类独有的方法。最终的结果看子类的实现。
1.3.2多态的向下转型(父类转子类)
语法格式: 子类 子类引用 = (子类)父类引用;
需要强转。
意义:使代码更具备普适性。
代码示例1:
class Animal1 {
public void eat() {
System.out.println("动物吃饭");
}
}
class Dog1 extends Animal1 {
@Override
public void eat() {
System.out.println("狗吃狗粮");
}
public void sleep() {
System.out.println("晚睡早起");
}
}
public class Demo4 {
public static void main(String[] args) {
// Animal1 animal = new Animal1();
// Dog1 dog = (Dog1)animal; //报错,类转换异常,Animal1类转换不了dog1类
// dog.eat();
// dog.sleep();
//解决方法:先向上转型,再向下转型
Animal1 animal = new Dog1();
Dog1 dog = (Dog1)animal;
dog.eat();
dog.sleep();
}
}
代码示例2:
class TestA {
//Object 是所有类的父类
public void test (Object obj ) {
//强转
String str = (String) obj;
System.out.println(str);
}
}
public class Demo4 {
public static void main(String[] args) {
TestA testA = new TestA();
//传入一个字符串,赋值给形参obj。String类是Object类的子类
//相当于一次向上转型
testA.test("狗蛋"); //打印结果是字符串类型的 狗蛋
}
}
1.4instanceof关键字
比较的操作符。用于判断对象的运行类型(创建对象等号的右边)是否是××类型或者××类型的子类,其返回值是一个布尔类型的数据。
语法格式: 对象引用 instanceof 类
目的:使在强转时不出问题。
代码示例1:
class AA {}
class BB extends AA {}
public class Demo1 {
public static void main(String[] args) {
BB bb = new BB();
AA aa = new AA();
//instanceof 的左边放的对象的引用,右边是类
System.out.println(bb instanceof BB);//true
System.out.println(aa instanceof BB);//false
//判断对象bb是否是AA的对象或者子类的对象
System.out.println(bb instanceof AA);//true
AA aa2 = new BB();
//看对象所属的类时,只看等号的右边
//aa2指向BB的对象
System.out.println(aa2 instanceof AA);//true
System.out.println(aa2 instanceof BB);//true
Object object = new Object();
//Object类是所有类的父类
System.out.println(object instanceof AA);//false
System.out.println(object instanceof Object);//true
String string = "qwer";
System.out.println(string instanceof Object);//true
}
}
代码示例2:
class Employee {}
class Monkey {
//方法的返回值是一个字符串
//万能Object类对象作为方法的参数
public String xixi(Object obj) {
//用instanceof对传入参数的运行类型进行判断
if (obj instanceof String) {
//强转一下
String string = (String)obj;
return "传给我的参数是字符串类型的数据";
} else if (obj instanceof Integer) {
Integer i1 = (Integer)obj;
return "传给我的参数是int类型的数据";
} else if (obj instanceof Employee) {
Employee employee = (Employee)obj;
return "传给我的参数是一个Employee对象";
} else {
return "参数不合法";
}
}
}
public class Demo3 {
public static void main(String[] args) {
Monkey monkey = new Monkey();
System.out.println(monkey.xixi("狗蛋")); //传给我的参数是字符串类型的数据
System.out.println(monkey.xixi(89)); //传给我的参数是int类型的数据
Employee employee = new Employee();
System.out.println(monkey.xixi(employee)); //传给我的参数是一个Employee对象
}
}