文章目录
java面向对象之三 多态
认识多态
多态通俗理解就是多种状态。在生活中就是同一种事物,由于条件的不同,产生的结果(状态)也是不同的。比如说:同样是打印机打印文档,由于打印机是黑白打印机还是彩色打印机,使用打印机打印出的文档也呈现为不同的结果。那么多态在代码中的体现指的是同一个引用类型,使用不同的实例而执行不同的操作。
多态作为面向对象的最后的一个特性,它存在三个必要的条件:也就是前面说到的继承,方法重写和父类引用指向子类的对象
package cn.zhz.Instance;
class Animal {
public void shout() {
System.out.println("叫了一声!");
}
}
class Dog extends Animal {
public void shout() {
System.out.println("旺旺旺!");
}
public void seeDoor() {
System.out.println("看门中....");
}
}
class Cat extends Animal {
public void shout() {
System.out.println("喵喵喵喵!");
}
}
public class TestPolym {
public static void main(String[] args) {
Animal a1 = new Cat(); // 向上可以自动转型
//传的具体是哪一个类就调用哪一个类的方法。大大提高了程序的可扩展性。
animalCry(a1);
Animal a2 = new Dog();
animalCry(a2);//a2为编译类型,Dog对象才是运行时类型。
//编写程序时,如果想调用运行时类型的方法,只能进行强制类型转换。
// 否则通不过编译器的检查。
Dog dog = (Dog) a2;//向下需要强制类型转换
dog.seeDoor();
}
// 有了多态,只需要让增加的这个类继承Animal类就可以了。
static void animalCry(Animal a) {
a.shout();
}
/* 如果没有多态,我们这里需要写很多重载的方法。
* 每增加一种动物,就需要重载一种动物的喊叫方法。非常麻烦。
static void animalCry(Dog d) {
d.shout();
}
static void animalCry(Cat c) {
c.shout();
}*/
}
在代码中有这样的两句:
Animal a1 = new Cat(); // 向上可以自动转型
Dog dog = (Dog) a2;//向下需要强制类型转换
这两句代码涉及到了对象的转型。
对象的向上和向下转型
对象的向上转型(对象的自动类型转换)
猫和狗一定是动物
在上面的的示例代码中Animal作为父类,Cat和Dog作为Animal的子类
Animal a1 = new Cat(); // 向上可以自动转型
父类引用指向子类对象,我们称这个过程为向上转型,属于自动类型转换。
对象的向下转型(对象的强制类型转换)
动物不一定是猫和狗,还可能包括别的动物比如说:鸭子
向上转型后的父类引用变量只能调用它编译类型的方法,不能调用它运行时类型的方法。这时,我们就需要进行类型的强制转换,我们称之为向下转型(也就是强制类型转换)
Animal a2 = new Dog();
Dog dog = (Dog) a2;//向下需要强制类型转换
在向下转型过程中,必须将引用变量转成真实的子类类型(运行时类型)否则会出现类型转换异常ClassCastException,可以使用instanceof来避免这种异常:
package cn.zhz.Instance;
public class Test {
public static void main(String[] args) {
Object obj = new String("hello");
if(obj instanceof String){
String str = (String)obj;
System.out.println(str.charAt(0));
}else if(obj instanceof StringBuffer){
StringBuffer str = (StringBuffer) obj;
System.out.println(str.charAt(0));
}
}
}
抽象类和抽象方法
抽象类是通过abstract方法定义规范,然后要求子类必须定义具体实现。
使用abstract修饰的方法,没有方法体,只有声明。定义的是一种“规范”,就是告诉子类必须要给抽象方法提供具体的实现。
//抽象类
abstract class Animal {
abstract public void shout(); //抽象方法
}
class Dog extends Animal {
//子类必须实现父类的抽象方法,否则编译错误
public void shout() {
System.out.println("汪汪汪!");
}
public void seeDoor(){
System.out.println("看门中....");
}
}
//测试抽象类
public class TestAbstractClass {
public static void main(String[] args) {
Dog a = new Dog();
a.shout();
a.seeDoor();
}
}
有抽象方法的类只能定义成抽象类
抽象类不能实例化,不能用new来实例化抽象类。
抽象类可以包含属性、方法、构造方法。
但是构造方法不能用来new实例,只能用来被子类调用。
抽象类只能用来被继承。
抽象方法必须被子类实现。
多态的使用:父类作为返回值
农场中有猫咪,狗还有鸭子,由于农场主人的热情好客,会根据朋友的要求送出动物
声明抽象动物类
package com.zhz.Kind;
//动物类
public abstract class Animal{
//动物叫
public abstract void shout();
}
声明狗类作为动物类的子类,并重写动物类中的shout方法
package com.zhz.Kind;
public class Dog extends Animal{
@Override
public void shout() {
System.out.println("汪汪汪");
}
}
package com.zhz.Kind;
public class Cat extends Animal{
@Override
public void shout() {
System.out.println("喵喵喵");
}
}
package com.zhz.Kind;
public class Duck extends Animal{
@Override
public void shout() {
System.out.println("嘎嘎嘎");
}
}
package com.zhz.Kind;
//农场主人
public class Master {
public Animal sendAnimal(int type) {
Animal animal = null;
switch (type) {
case 1: {
animal = new Cat();
break;
}
case 2: {
animal = new Dog();
break;
}
case 3: {
animal = new Duck();
break;
}
default: {
System.out.println("对不起,我们的农场中没有这样的动物");
}
}
return animal;
}
// //给朋友赠送动物作为礼物
// public Cat sendCat(){
// return new Cat();
// }
// public Dog sendDog(){
// return new Dog();
// }
// public Duck sendDuck(){
// return new Duck();
// }
}
package com.zhz.Instance;
import java.util.Scanner;
import com.zhz.Kind.Animal;
import com.zhz.Kind.Cat;
import com.zhz.Kind.Dog;
import com.zhz.Kind.Duck;
import com.zhz.Kind.Master;
public class SendTest {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
Master master = new Master();
System.out.println("朋友,您喜欢什么动物:1.猫2.狗3.鸭子");
int type = input.nextInt();
if (type >= 4) {
System.out.println("对不起,这里没有这样的动物");
} else {
Animal animal = master.sendAnimal(type);
// 多态:根据具体的动物的子类,调用重写后的方法
animal.shout();
}
}
}
父类作为返回值的练习
package com.zhz.Kind;
public abstract class Goods {
public abstract void printPrice();
}
package com.zhz.Kind;
public class TVs extends Goods {
public void printPrice() {
System.out.println("打印输出电视价格");
}
}
package com.zhz.Kind;
public class Foods extends Goods {
public void printPrice() {
System.out.println("打印输出食品价格");
}
}
package com.zhz.Kind;
public class Factory {
public Goods getGoods(String str) {
if (str.equals("food")) {
return new Foods();
} else {
return new TVs();
}
}
}
package com.zhz.Instance;
import com.zhz.Kind.Factory;
import com.zhz.Kind.Goods;
public class GoodsTest {
public static void main(String[] args) {
Factory factory = new Factory();
Goods goods = factory.getGoods("food");
goods.printPrice();
goods = factory.getGoods("tvs");
goods.printPrice();
}
}