欢迎来到我的主页:【一只认真写代码的程序猿】
本篇文章收录于专栏【小小爪哇】
如果这篇文章对你有帮助,希望点赞收藏加关注啦~
目录
1 多态
多态存在的三个必要条件
- 继承
- 重写
- 父类引用指向子类对象:Parent p = new Child();
public class Test {
public static void main(String[] args) {
show(new Cat()); // 以 Cat 对象调用 show 方法
show(new Dog()); // 以 Dog 对象调用 show 方法
Animal a = new Cat(); // 向上转型
a.eat(); // 调用的是 Cat 的 eat
Cat c = (Cat)a; // 向下转型
c.work(); // 调用的是 Cat 的 work
}
public static void show(Animal a) {
a.eat();
// 类型判断
if (a instanceof Cat) { // 猫做的事情
Cat c = (Cat)a;
c.work();
} else if (a instanceof Dog) { // 狗做的事情
Dog c = (Dog)a;
c.work();
}
}
}
abstract class Animal {
abstract void eat();
}
class Cat extends Animal {
public void eat() {
System.out.println("吃鱼");
}
public void work() {
System.out.println("抓老鼠");
}
}
class Dog extends Animal {
public void eat() {
System.out.println("吃骨头");
}
public void work() {
System.out.println("看家");
}
}
2 向上转型
多态本身是子类类型向父类类型向上转换的过程,这个过程是默认的。
如:Animal animal = new Dog();
本质:父类的引用指向了子类的对象3)
语法:父类类型引用名=new 子类类型()
特点:编译类型看左边,运行类型看右边。可以调用父类中的所有成员(需遵守访问权限)不能调用子类中特有成员。
3 向下转型
父类类型向子类类型向下转换的过程,这个过程是强制的。
一个已经向上转型的子类对象,将父类引用转为子类引用,可以使用强制类型转换的格式,便是向下转型。
如:Dog dog = (Dog) animal;
语法:子类类型 引用名=(子类类型) 父类引用
特点1:只能强转父类的引用,不能强转父类的对象。
特点2:要求父类的引用必须指向的是当前目标类型的对象。当向下转型后,可以调用子类类型中所有的成员。
当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误。也就是说,不能调用子类拥有 而父类没有的方法。编译都错误,更别说运行了。所以,想要调用子类特有的方法,必须做向下转型。
package day111;
/**
* @ClassName Animal
* @Description
* @Author NYX
* @Date 2024/11/25 16:56
* @Version V1.0
*/
public class Test{
public static void main(String[] args) {
//向上转型
Animal animal = new Cat();
//1、可以调用父类方法(遵循权限)
//2、不能调用子类特有的成员,因为成员调用由编译来决定
// animal.catch是一个error
animal.eat();
animal.sleep();
//向下转型
Cat cat = (Cat) animal;
cat.catchMouse();
// Dog dog = (Dog) animal;
// dog.eat();运行时error;java.lang.ClassCastException
}
}
class Animal {
String name = "动物";
int age = 10;
public void sleep(){
System.out.println("动物睡觉");
}
public void eat(){
System.out.println("动物吃");
}
}
class Cat extends Animal{
@Override
public void eat(){
System.out.println("猫吃鱼");
}
public void catchMouse(){
System.out.println("猫抓老鼠");
}
}
class Dog extends Animal{
@Override
public void eat(){
System.out.println("狗吃骨头");
}
}
4 属性
属性不存在重写,属性看编译类型。
5 instanceOf
用于判断对象的运行类型是否为 XX 类型或 XX 类型的子类型
package day111;
/**
* @ClassName instanceOfUse
* @Description
* @Date 2024/11/25 17:15
* @Version V1.0
*/
//用于判断对象的运行类型是否为 XX 类型或 XX 类型的子类型
public class instanceOfUse {
public static void main(String[] args) {
BB bb = new BB();
System.out.println(bb instanceof BB);// true
System.out.println(bb instanceof AA);// true
//aa 编译类型 AA, 运行类型是 BB
//BB 是 AA 子类
AA aa = new BB();
System.out.println(aa instanceof AA);//true
System.out.println(aa instanceof BB);//true
Object obj = new Object();
System.out.println(obj instanceof AA);//false
String str = "hello";
System.out.println(str instanceof Object);//true
}
}
class AA {
}
class BB extends AA {
}
6 动态绑定
package day111;
/**
* @ClassName DynamicBinding
* @Description
* @Date 2024/11/25 17:28
* @Version V1.0
*/
public class DynamicBinding {
public static void main(String[] args) {
A a = new B();//向上转型
System.out.println(a.sum()); //40
System.out.println(a.sumI());//30
}
}
class A{
public int i=10;
public int sum(){
return getI()+10;
}
public int sumI(){
return i+10;
}
public int getI(){
return i;
}
}
class B extends A{
public int i=20;
public int sum(){
return i+20;
}
public int sumI(){
return i+10;
}
public int getI(){
return i;
}
}