Java多态

多态(polymorphism)

poly + morphism

许多 形态 即多种形态

extends继承或者implements实现,是多态性的前提。

在这里插入图片描述

多态意味着父类型可以引用子类型的对象

继承关系使一个子类能继承父类的特征,并且附加一些新特征。子类是它的父类的特殊化,每个子类的实例都是其父类的实例,但是反过来并不成立。例:每个圆都是几何对象,但并非每个几何对象都是圆。因此,总可以将子类的实例传给需要父类型的参数

Eg1:

//父类
public class Father {
	public void method() {
		System.out.println("父类方法");
	}
	public void methodf() {
		System.out.println("父类特有方法");
	}
}
//子类
public class Son extends Father{
	@Override
	public void method() {
		System.out.println("子类方法");
	}
}
/*
 代码体现多态性的一句话,父类引用指向子类对象
 
 格式:
 父类名称 对象名 = new 子类名称();
 */
public class Demo1 {
	public static void main(String[] args) {
		Father obj = new Son();
		obj.method();//输出 子类方法
		obj.methodf();//输出 父类特有方法
	}
}

Eg2:

public class Father {
	int num=20;
	public void method() {
		System.out.println(num);
	}
}
public class Son extends Father{
	int num=10;
    int age=16;
	@Override
	public void method() {
		System.out.println(num);
	}
}
/*
 访问成员变量的两种方式:
 
 1.直接通过对象名称访问成员变量:等号左边是谁,优先用谁,没有则向上找
 2.间接通过成员方法访问:看该方法属于谁,优先用谁,没有则向上找
 */
public class Demo1 {
	public static void main(String[] args) {
		Father obj = new Son();
		System.out.println(obj.num);//输出20
       // System.out.println(obj.age);错误写法,不会向下找的,只会向上找,找objcect,而object里面肯定没有age
        obj.method();//输出10,如果子类没有方法重写的话就输出20
	}
}

Eg3:

public class Father {
	public void method() {
		System.out.println("父类方法");
	}
	public void methodf() {
		System.out.println("父类特有方法");
	}
}
public class Son extends Father{
	public void method() {
		System.out.println("子类方法");
	}
	public void methods() {
		System.out.println("子类特有方法");
	}
}
/*
 在多态的代码中,成员方法的访问规则是:
 看new的是谁,就优先用谁,没有则向上找
  
  编译看左边,运行看右边
 */
public class Demo1 {
	public static void main(String[] args) {
		Father obj = new Son();
		obj.method();
		obj.methodf();
		obj.methods();//编译报错,因为父类没有methods这个方法
	}
}

总结:多态:基类型对象访问派生类重写的方法

向上转型

对象的向上转型,其实就是多态写法

父类名称 对象名 = new 子类名称();   //Animal animal = new Cat()  创建了一只猫,把他当作动物
含义:右侧创建一个子类对象,把他当做父类来看待使用
    
==注==:向上转型一定是安全的,从小范围到大范围。但也有一个弊端,就是对象一旦向上转型成父类,那么就无法再调用子类原本特有的内容。(即上面Demo1里面注释编译报错的那一行,因为methods是子类特有的内容),此时就有了向下转型
 类似于:
  double num=100;//正确,int->double 
向下转型

对象的向下转型,其实就是一个【还原】的动作

格式:子类名称 对象名 = (子类名称) 父类对象;(类似于强制类型转换)

含义:将父类对象,还原成本来的子类对象

Animal animal = new Cat();//本来是猫,向上转型为动物

Cat cat = (Cat) animal;//本来是猫,已经被当作动物了,现在还原成原来的猫

注意:a.必须保证对象本来创建的时候,就是猫,才能向下转型成为猫,如果对象原来创建的时候不是猫,现在非要向下转型成为猫,就会报错。(编译不会出错,运行会出错)

那怎么知道父类引用的对象中本来是什么子类呢?

这时就需要使用instanceof

public class Demo2 {
	public static void main(String[] args) {
	giveMeAPet(new Dog());
	}
}

public static void giveMeAPet(Animal animal){
    if(animal instanceof Dog){
        Dog dog = (Dog) animal;
        dog.watchHourse();
    }
    if(animal instanceof Cat){
		Cat.cat = (Cat) animal;
        cat.catchHouse();
    }
}
//给我了一只动物,但我只知道她是动物,所以此时要用instanceof判断他是什么,从而物尽其用。
多态的应用

1.循环调用基类对象,访问不同派生类方法

public static void main(String[] args) {
GradedActivity[] tests = new GradedActivity[3];

    // 第一次考试采用五级计分制,考了75
    tests[0] = new GradedActivity();
    tests[0].setScore(75);

    // 第二次考试采用二级计分制(P或者F)。总共20题,每题分值相同,考生答错5题。
    // 通过的最低分数线是60分
    tests[1] = new PassFailExam(20, 5, 60);
 
    // 第三次是期末考试也采用五级计分制. 总共50题,每题分值相同,考试答错7题
	tests[2] = new FinalExam(50, 7);

    // 显示每次考试的分数和等级
	for(int i=0; i<tests.length; i++){
   		showValue(tests[i]);
	}
}

	public static void showValue(GradedActivity exam){
		System.out.println("Score: " + exam.getScore()+ "\t" + 
		"Grade: " + exam.getGrade());
	}

2.实参是派生类,形参是基类

抽象方法

图形类(Geometry)是矩形和圆形等具体形状类的共同父类,他有一个getArea方法的功能是计算图形的面积,但是在图形类中并不知道具体的形状,因此无法计算,也就是说,getArea方法的方法在父类中实际上没有任何意义。

解决办法:通过abstract关键字将getArea方法修饰为抽象的,此时的方法称为抽象方法
抽象方法是出现在基类中的一种方法,但要求在派生类中被重写。(如果派生类没有重写抽象方法,编译器就会报错,抽象方法被用来确保派生类会实现这个方法)

格式:访问修饰符 abstract 返回类型 方法名(参数列表);

例:public abstract void getArea();//关键字abstract 出现在方法头中,方法头以分号结尾

若类含有抽象方法,则类必须以abstract关键字声明为抽象类。
格式: public abstract class 类名

注意

1.不论抽象类是否含抽象方法,其都不允许实例化,即不能创建抽象类的对象,因为其描述的是抽象概念。它只能作为其他类的基类。
2.若父类是抽象类,且子类不想成为抽象类,则子类必须将父类中的所有抽象方法重写为带方法体的普通方法,否则子类仍必须是抽象类。

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java多态指的是同一个方法名可以根据不同的对象调用出不同的行为。具体来说,多态是一种面向对象编程的特性,实现多态的方式主要有两种:方法重载和方法覆盖。方法重载指的是在一个类定义多个同名方法,但这些方法有不同的参数列表,编译器会根据参数列表的不同选择合适的方法进行调用。方法覆盖指的是子类重写父类的方法,使得在使用父类对象调用该方法时,实际调用的是子类的方法。 多态的好处在于,它可以提高代码的灵活性和可扩展性。通过多态,我们可以为不同的对象提供不同的行为,从而使得程序更加具有扩展性。此外,多态还可以让程序的调用更加简洁、清晰,提高了代码的可读性和可维护性。 下面是一个简单的Java多态的例子: ```Java class Animal { public void makeSound() { System.out.println("动物发出声音"); } } class Cat extends Animal { public void makeSound() { System.out.println("猫发出“喵喵”的声音"); } } class Dog extends Animal { public void makeSound() { System.out.println("狗发出“汪汪”的声音"); } } public class PolymorphismExample { public static void main(String[] args) { Animal animal1 = new Animal(); Animal animal2 = new Cat(); Animal animal3 = new Dog(); animal1.makeSound(); // 动物发出声音 animal2.makeSound(); // 猫发出“喵喵”的声音 animal3.makeSound(); // 狗发出“汪汪”的声音 } } ``` 在上面的例子,Animal是一个父类,Cat和Dog是Animal的子类。Animal类定义了一个makeSound()方法,Cat和Dog类分别重写了这个方法。在main()方法,我们创建了三个Animal类型的对象,并分别调用它们的makeSound()方法。由于animal2和animal3都是Animal类型的对象,但实际上它们分别是Cat和Dog类型的对象,因此在调用它们的makeSound()方法时,实际上是调用了它们各自的实现,也就是Cat类和Dog类重写的makeSound()方法。这就是Java多态的表现。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值