fantasticDream

面向对象编程----多态_基本概念_强制转型问题_instanceof运算符

多态

Polymorphism

在编程中,可以分为两大阶段,一个程序想要运行可以分为编译和运行。

编译:编译的时候使用父类,把多种情况都列举出来。如:说出多种情况

运行:运行的时候,只有一种情况,是什么就是什么。如:做现实的事情

多态性是OOP中的一个重要特性,主要是用来实现动态联编的,换句话说,就是程序的最终状态只有在执行过程中才被决定而非在编译期间就决定了。
这对于大型系统来说能提高系统的灵活性和扩展性
Java中如何实现多态?使用多态的好处?
引用变量的两种类型:
  编译时类型模糊一点,一般是一个父类)
  由声明时的类型决定。
  运行时类型运行时,具体是哪个子类就是哪个子类)
  由实际对应的对象类型决定。
多态的存在要有3个必要条件:
  要有继承要有方法重写父类引用指向子类对象。

package cn.bjsxt.oop.polymorphism;
/**
* animal动物
* @author 神奇的梦
*
*/

public class Animal {
public void voice() {
System.out.println("普通动物的叫声");
}
}
class Cat extends Animal {
public void voice() {
System.out.println("喵喵喵");
}
public void catchMouse() {
System.out.println("抓老鼠");
}
}
class Dog extends Animal {
public void voice() {
System.out.println("汪汪汪");
}
public void seeDoor() {
System.out.println("看门");
}
}
class Tiger extends Animal {
public void voice() {
System.out.println("哼哼哼");
}


}
class Pig extends Animal {
public void voice() {
System.out.println("哼哼哼");
}
}

package cn.bjsxt.oop.polymorphism;
/**
*
* 多态是方法的多态,属性没有多态。
* @author 神奇的梦
*
*/
public class Test {
/**/
// 编译时的类型声明时的类型决定
// Animal就包含了子类的集中情况  编译时类型

在这里是这么回事Cat c = new Cat();Animal a=c;相当于Animal a=new Cat();
public static void testAnimalVoice(Animal c) {
// 通过调用实例化对象c找到里面的方法voice方法
c.voice();
// instanceof判断一个对象是不是这个类型的对象
// cCat类的实例对象
if(c instanceof Cat) {
// 编译器不认c还是Animal,所以要强转为Cat
// 把c强转为Cat然后调用catchMouse()抓老鼠方法
((Cat)c).catchMouse();
  }
}

/*
public static void testAnimalVoice(Animal c,Animal dc,Animal p) {
// 通过调用实例化对象c找到里面的方法voice方法
c.voice();
dc.voice();
p.voice();
// c.voicel();
}
*/

// public static void testAnimalVoice(Cat c) {
// 通过调用实例化对象c找到里面的方法voice方法
// c.voice();
// c.voicel();
// }


/*
// 如果没有多态可以这么做
// 可以调用类Cat的重载方法
// 编译时的类型由声明是的类型决定
public static void testAnimalVoice(Cat c) {
// 通过调用实例化对象c找到里面的方法voice方法
c.voice();
}
// 编译时的类型由声明是的类型决定
// 可以调用类Dog的重载方法
public static void testAnimalVoice(Dog c) {
// 通过调用实例化对象c找到里面的方法voice方法
c.voice();
}
// 编译时的类型由声明是的类型决定
// 可以调用PIg的重载方法
public static void testAnimalVoice(Pig c) {
// 通过调用实例化对象c找到里面的方法voice方法
c.voice();
}*/
// 如果有十个类写十个方法就可以了


public static void main(String[] args) {
// new一个模板对象c
// new Cat()相当于运行时类型,实际上是一个Cat
// 编译时的类型由声明是的类型决定
Cat t = new Cat();
testAnimalVoice(t);
// Cat继承于Animal实际上也属于Animal的一个子类
// Cat c = new Cat();
// Animal a=c;


// Cat c = new Cat();Animal a=c;相当于Animal a=new Cat();
// 这样就构成一个多态了
// 父类的引用Animal指向了一个子类的对象
// 想要运行必须先要通过编译
// 编译器只认声明类 写的是Animal 它就是Animal 别的它不管它只管编译
Animal a=new Cat();
// 父类的引用Animal指向了一个子类的对象
Animal b=new Dog();
// 父类的引用Animal指向了一个子类的对象
Animal c=new Pig();
Animal d=new Tiger();
调用重写后的继承子类

一个类里面只有一个方法可以这样调用
testAnimalVoice(a);
testAnimalVoice(b);
testAnimalVoice(c);
一个类里面有多个方法这样调用
// The method catchMouse() is undefined for the type Animal
// 类型Animal的方法catchMouse()未定义
// a.catchMouse();//怎么转型呢

// 强制转型

// 将变量a强制类型转换为(Cat)类
Cat a2 =(Cat)a;
// 调用变量实例化a2里面的方法catchMouse()
a2.catchMouse();

a2.voice();


// 类型不一样  转不了,更调不了 是错的
Cat ca2 =(Cat)c;
// 调用变量实例化a2里面的方法catchMouse()
ca2.catchMouse();

// 给普通方法testAnimalVoice()传参对象c
// 通过实例化对象c传参为局部变量从而调用方法内c.voice()方法
// testAnimalVoice(c);

Dog dc = new Dog();
// 给普通方法testAnimalVoice()传参对象dc
// 通过实例化对象dc传参为局部变量c从而调用方法内c.voice()方法
// testAnimalVoice(dc);
Pig p = new Pig();
// testAnimalVoice(p);
// testAnimalVoice(c,dc,p);
}
}

posted on   神奇的梦  阅读(24)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

导航

统计

点击右上角即可分享
微信分享提示