java多态性
java多态练习题

java多态练习题Java多态练习题Java是一种面向对象的编程语言,其中的多态性是其最重要的特性之一。
通过多态,我们可以实现代码的灵活性和可扩展性。
在这篇文章中,我们将通过一些练习题来加深对Java多态性的理解。
练习一:动物的多态假设有一个动物类Animal,它有一个方法叫做makeSound(),用于输出动物的叫声。
现在我们派生出了两个子类Dog和Cat,它们分别重写了makeSound()方法,分别输出"汪汪汪"和"喵喵喵"。
现在我们创建一个Animal类型的数组,数组中存放了不同的动物对象,包括Dog和Cat。
我们遍历数组,调用每个动物对象的makeSound()方法,观察输出结果。
代码示例:```javaclass Animal {public void makeSound() {System.out.println("动物发出叫声");}}class Dog extends Animal {@Overridepublic void makeSound() {System.out.println("汪汪汪");}}class Cat extends Animal {@Overridepublic void makeSound() {System.out.println("喵喵喵");}}public class PolymorphismExample {public static void main(String[] args) { Animal[] animals = new Animal[3]; animals[0] = new Dog();animals[1] = new Cat();animals[2] = new Dog();for (Animal animal : animals) {animal.makeSound();}}}```运行结果:```汪汪汪喵喵喵汪汪汪```通过这个练习题,我们可以看到多态的作用。
【Java】面向对象的四个基本特征:唯一性、分类性、继承性和多态性

【Java】⾯向对象的四个基本特征:唯⼀性、分类性、继承性
和多态性
1.唯⼀性
唯⼀性是指每个对象都是唯⼀的,具有唯⼀标识符。
在对象的整个⽣命周期中,标识符是⼀成不变的,系统可通过该标识符,在内存中找到相应对象。
2.分类性
分类性是指将具有⼀致属性和⾏为的对象抽象成类,只保留与应⽤有关的性质,其他内容忽略。
任何类的划分都是主观的,但必须与具体应⽤有关。
3.继承性
继承性是指⼦类⾃动继承⽗类的属性和⽅法,并且可以在⽗类的基础上加⼊若⼲新内容。
例如,“⼈”这个类抽象了这个群体的基本特征,⽽“学⽣”和“⽼师”除了具备“⼈”所定义的基础特性外,各⾃⼜具有各⾃的新特性。
继承性是⾯向对象程序设计语⾔不同于其他语⾔的最重要特点。
通过类的继承,可使公共的特性能够共享,提⾼代码的可重⽤性、减少冗余,同时简化了对象、类的创建⼯作,规范了类的等级结构。
4.多态性
多态性是指不同对象,在收到同⼀消息后,可产⽣不同结果,具有不同表现⾏为。
多态性允许每个对象以⾃⾝的⽅法去响应共同消息,以此增强软件的灵活性和可重⽤性。
Java基本概念:多态

Java基本概念:多态⼀、简介描述:多态性是⾯向对象编程中的⼀个重要特性,主要是⽤来实现动态联编的。
换句话说,就是程序的最终状态只有在执⾏过程中才被决定,⽽⾮在编译期间就决定了。
这对于⼤型系统来说能提⾼系统的灵活性和扩展性。
多态允许相同类域的不同对象对同⼀消息做出响应。
即同⼀消息可以根据发送对象的不同⽽采⽤多种不同的⾏为⽅式。
多态可以让我们不⽤关⼼某个对象到底是什么具体类型,就可以使⽤该对象的某些⽅法,从⽽实现更加灵活的编程,提⾼系统的可扩展性。
如果对象的编译时类型和运⾏时类型不⼀致,就会造成多态。
存在条件:1. 类之间有继承关系。
2. ⼦类重写⽗类⽅法。
3. ⽗类引⽤指向⼦类对象。
注意:多态是⽅法的多态,属性没有多态性。
⼀个对象的实际类型是确定的,但是可以指向这个对象的引⽤的类型,却是可以是这对象实际类型的任意⽗类型。
⼦类继承⽗类,调⽤⽅法,如果该⽅法在⼦类中没有重写,那么就是调⽤的是⼦类继承⽗类的⽅法,如果重写了,那么调⽤的就是重写之后的⽅法。
'protected'修饰的⽗类⽅法可以被⼦类见到,也可以被⼦类重写,但是它是⽆法被外部所引⽤的,所以没有多态性。
通过⼀个变量调⽤其引⽤的对象的⼀个⽅法,编译器是否能让其编译通过,主要是看该变量类型的类中有没有定义该⽅法,如果有则编译通过,如果没有则编译报错。
⽽不是看这个变量所引⽤的对象中有没有该⽅法。
Java中的⽅法调⽤,是运⾏时动态和对象绑定的,不到运⾏的时候,是不知道到底哪个⽅法被调⽤的。
编写程序时,如果想调⽤运⾏时类型的⽅法,只能进⾏类型转换,不然通不过编译器的检查。
但是如果两个没有关联的类进⾏强制转换,会报类型转换异常:ClassCastException。
⽰例:public class Test {public static void main(String[] args) {/* 编译看左,运⾏看右 */Student student = new Student();/* 变量person是可以指向Person类型或其⼦类型的对象,所以可以指向Student类型对象 */Person person = new Student();/* 变量student能调⽤的⽅法是Student类中有的⽅法(包括继承过来的) */student.say();//Student/* 变量person能调⽤的⽅法是Person类中有的⽅法 */person.say();//Student}}class Person {public void say() {System.out.println("Person");}}class Student extends Person {public void say() {System.out.println("Student");}}⼆、重写、重载、多态的关系1. 重载是编译时多态调⽤重载的⽅法,在编译期间就要确定调⽤的⽅法是谁,如果不能确定则编译报错。
在JAVA中有两种多态指的是什么

同问 在JAVA中有两种多态指的是什么 2009-01-15 14:32 提问者: mdydyy |浏览次数:2218次
我来帮他解答
精彩回答
2009-01-15 15:11在JAVA中有两种多态是指:运行时多态和编译时多态。关于类的多态性简介如下: 多态(polymorphism)意为一个名字可具有多种语义.在程序设计语言中,多态性是指”一种定义,多种实现”.例如,运算符+有多种含义,究竟执行哪种运算取决于参加运算的操作数类型: 1+2 //加法运算符 “1” + “2” //字符串连接运算,操作数是字符串 多态性是面向对象的核心特征之一,类的多态性提供类中成员设计的灵活性和方法执行的多样性. 1、类多态性表现 (1)方法重载 重载表现为同一个类中方法的多态性.一个类生命多个重载方法就是为一种功能提供多种实现.编译时,根据方法实际参数的数据类型\个数和次序,决定究竟应该执行重载方法中的哪一个. (2)子类重定义从父类继承来的成员 当子类从父类继承来的成员不适合子类时,子类不能删除它们,但可以重定义它们,使弗雷成员适应子类的新需求.子类重定义父类成员,同名成员在父类与子类之间表现出多态性,父类对象引用父类成员,子类对象引用子类成员,不会产生冲突和混乱. 子类可重定义父类的同名成员变量,称子类隐藏父类成员变量.子类也可以重定义父类的同名成员方法,当子类方法的参数列表与父类方法参数列表完全相同时,称为子类方法覆盖(override)父类方法。覆盖父类方法时,子类方法的访问权限不能小于父类方法的权限。 由于Object类的equals()方法比较两个对象的引用是否相等而不是值是否相等,因此一个类要覆盖Object类的equals()方法,提供本类两个对象比较相等方法. 覆盖表现为父类与子类之间方法的多态性.java 寻找执行方法的原则是:从对象所属的类开始,寻找匹配的方法执行,如果当前类中没有匹配的方法,则逐层向上依次在父类或祖先类中寻找匹配方法,直到Object类. 2、super 引用 在子类的成员方法中,可以使用代词super引用父类成员.super引用的语法如下: super([参数列表]) //在子类的构造方法体中,调用父类的构造方法 super.成员变量 //当子类隐藏父类成员变量时,引用父类同名成员变量 super.成员方法([参数列表]) //当子类覆盖父类成员方法时,调用父类同名成员方法 *注意:super引用没有单独使用的语法 3、多态性有两种: 1)编译时多态性 对于多个同名方法,如果在编译时能够确定执行同名方法中的哪一个,则称为编译时多态性. 2)运行时多态性 如果在编译时不能确定,只能在运行时才能确定执行多个同名方法中的哪一个,则称为运行时多态性. 方法覆盖表现出两种多态性,当对象获得本类实例时,为编译时多态性,否则为运行时多态性,例如: XXXX x1 = new XXXX(参数列表); //对象获得本类实例,对象与其引用的实例类型一致 XXX xx1 = new XXX(参数列表); x1.toString(); //编译时多态性,执行XXX类的方法. xx1.toString(); //编译时多态性,执行XXXX类覆盖的方法. XXXX为XXX的父类. 由于子类对象既是父类对象,父类对象与子类对象之间具有赋值相容性,父类对象能够被赋值为子类对象.例如, XXXX x2 = new XXX(参数列表); //父类对象获得子类实例,子类对象即是父类对象 x2.toString(); //运行时多态 x2声明为父类对象却获得子类XXX的实例,那么x2.toString()究竟执行父类方法还是执行子类覆盖的方法呢? 这分为两种情况: 取决于子类是否覆盖父类方法.如果子类覆盖父类方法,则执行子类方法; 如果没有覆盖,则执行父类方法. 在编译时,仅仅依据对象所属的类,系统无法确定到底应该执行那个类的方法,只有运行时才能确定,因此这是运行时多态. 父类对象并不能执行所有的子类方法,只能执行那些父类中声明\子类覆盖的子类方法.
java多态演讲ppt

sram实现多态三个条件:
1:继承 2:重写(重写父类继承的方法) 3:父类引用指向字类对象
sramwww.
安博思软
多态的实现:通过继承实现
JAVA中,一个类之能有一个父类,不能多继承。一个父类可 以有多个子类,而在子类里可以重写父类的方法,这样每个子
sramwww.
安博思软
sramwww.
安博思软
多态性有两种:
编译时多态性(静态绑 定)
运行时多态性(动态 绑定)
如果在编译时不能确定,只能 , 在运行时才能确定执行多个 同名方法中的哪一个,则称为 运行时多态性。
对于多个同名方法,如果在编 译时能够确定执行同名方法 中的哪一个,则称为编译时多 态性。
sramwww.
安博思软
多态的实现:通过接口实现
继承 单继承 一个类只能继承一个父类! 一个类只能继承一个父类!
接口
多实现
一个类可以同时实现多个接口! 类可以同时实现多个接口! 同时实现多个接口
一个接口类型变量也可以指向其实现类的实例,这也是 个接口类型变量也可以指向其实现类的实例,这也是
输出结果:
我知道错了,别打了! 为什么打我?我做错什么了! 我跑,你打不着!
//子类3 public class Son3 extends Father{ //重写父类打孩子方法 public void hitChild(){ System.out.println("我跑,你打不着!"); }}
//子类1 public class Son1 extends Father{ //重写父类打孩子方法 public void hitChild(){ System.out.println("我知道错了,别打了!"); }}
JAVA多态性 ppt课件

a.fun1();
// 此方法被子类覆写过
}
}
PPT课件
6
对象的向下转型
class A{ public void fun1(){
// 定义类A // 定义fun1()方法
System.out.println("A --> public void fun1(){}") ;
} public void fun2(){
PPT课件
5
对象的向上转型
class A{ public void fun1(){
// 定义类A // 定义fun1()方法
System.out.println("A --> public void fun1(){}") ;
} public void fun2(){
// 定义fun2()方法
this.fun1() ;
A a = new B() ;
// 发生了向上转型的关系,子类 --> 父类
B b = (B)a ;
// 此时发生了向下转型关系
b.fun1() ;
// 调用方法被覆写的方法
b.fun2() ;
// 调用父类的方法
b.fun3() ;
// 调用子类自己定义的方法
}
}
PPT课件
7
多态禁忌
•千万不要出现这样的操作:就是将父类对象转换成为子类是类型 – Animal a=new Animal(); – Dog d4=(Dog)a;//类造型异常
}
}; class B extends A{
public void fun1(){
// 子类通过extends继承父类 // 覆写父类中的fun1()方法
java 多态笔试题

当然,我可以给你提供一些关于Java多态的笔试题。
请注意,以下问题仅供参考。
1. 什么是Java中的多态性?
2. 如何实现多态性?
3. 什么是动态绑定(Dynamic Binding)?
4. Java中的重写(Overriding)和重载(Overloading)的区别是什么?
5. 简要解释一下抽象类和接口的作用,并比较它们之间的异同点。
6. 能否在Java中创建一个抽象类的实例?为什么?
7. 是否可以同时使用final和abstract关键字修饰一个类或方法?为什么?
8. 什么是向上转型(Upcasting)和向下转型(Downcasting)?它们在多态中的作用是什么?
9. 请解释一下Java中的instanceof关键字的作用和用法。
10. 在Java中如何实现方法的重载?
这些问题应该可以帮助你巩固对Java多态的理解。
请记住,理论知识和实际编程经验相结合是非常重要的。
祝你好运!如果你有其他问题,请随时提问。
Java的动态多态性

angle 类和Trigle 类的对象给t 、 赋值, r 利
4 结语
多态性提高了程序的抽象程度和简洁 性,降低 了 类和程序模块之间的祸合性,提 高了类模块之间的封闭性。实现了 “ 一个接 口,多个 方法” 。
参考文献 【 朱喜福, ] 1 编著. J va 程序设计, a 清华大学出 版社 .
盛. 娜井
昊金秀
(黄冈职业技术学院
湖北黄冈
435002 )
摘 要: 运行时多 态性是面向 对象程序设计代码重用的一个最强 大机制,动态性的 概念也可以被说成 “ 接口 一个 ,多个方 。 av a 法” J
实现运行时多态性的基础是动态方法调度,它是一种在运行时而不是在编译时动态绑定的机制。 关键词: 覆盖 多态性 动态多 态性 上溯造型 中图分类号: T P 3 文献标识码: A 文章编号: 1672一 3791(2007)07(b卜0246一 01 面向对象的程序设计有三大特点: 封装, 继承和多态。多态提供了另一个层面的接口 与实现分离,也就是说把做什么和怎么做分 离开来。多态性是一项很重要的技术。 个对象在调用与其子类同名成员函数 ( 函数 原型一致) 时,调用规则是依据对象在实例 化时而非定义时的类型相应地调用对应类中 的同名成员函数,是在程序执行的过程中根 据不同对象类型有不同的绑定。 2 上述代码中Rect angle 类和T rigle 类都是 Sha pe 类的子类, 程序中定义了Shape 类的 两个引用对象t 和r , 分别通过创 建子类Re 一 t c
住砚. .
(目加 翻 州翻,
使用单排深层搅拌桩作防水帷幕时必须设反 循环观测井。 ④有邻近建筑物的基坑支护桩配筋宜用 双面配筋 ,以备加内撑时使用。 ⑤桩顶的圈梁作用重大,起调节跨中与 附近桩内力的作用,应予重视。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Java的多态性面向对象编程有三个特征,即封装、继承和多态。
封装隐藏了类的内部实现机制,从而可以在不影响使用者的前提下改变类的内部结构,同时保护了数据。
继承是为了重用父类代码,同时为实现多态性作准备。
那么什么是多态呢?方法的重写、重载与动态连接构成多态性。
Java之所以引入多态的概念,原因之一是它在类的继承问题上和C++不同,后者允许多继承,这确实给其带来的非常强大的功能,但是复杂的继承关系也给C++开发者带来了更大的麻烦,为了规避风险,Java只允许单继承,派生类与基类间有IS-A的关系(即“猫”is a “动物”)。
这样做虽然保证了继承关系的简单明了,但是势必在功能上有很大的限制,所以,Java引入了多态性的概念以弥补这点的不足,此外,抽象类和接口也是解决单继承规定限制的重要手段。
同时,多态也是面向对象编程的精髓所在。
要理解多态性,首先要知道什么是“向上转型”。
我定义了一个子类Cat,它继承了Animal类,那么后者就是前者是父类。
我可以通过Cat c = new Cat();实例化一个Cat的对象,这个不难理解。
但当我这样定义时:Animal a = new Cat();这代表什么意思呢?很简单,它表示我定义了一个Animal类型的引用,指向新建的Cat类型的对象。
由于Cat是继承自它的父类Animal,所以Animal类型的引用是可以指向Cat类型的对象的。
那么这样做有什么意义呢?因为子类是对父类的一个改进和扩充,所以一般子类在功能上较父类更强大,属性较父类更独特,定义一个父类类型的引用指向一个子类的对象既可以使用子类强大的功能,又可以抽取父类的共性。
所以,父类类型的引用可以调用父类中定义的所有属性和方法,而对于子类中定义而父类中没有的方法,它是无可奈何的;同时,父类中的一个方法只有在在父类中定义而在子类中没有重写的情况下,才可以被父类类型的引用调用;对于父类中定义的方法,如果子类中重写了该方法,那么父类类型的引用将会调用子类中的这个方法,这就是动态连接。
看下面这段程序:class Father{public void func1(){func2();}//这是父类中的func2()方法,因为下面的子类中重写了该方法//所以在父类类型的引用中调用时,这个方法将不再有效//取而代之的是将调用子类中重写的func2()方法public void func2(){System.out.println("AAA");}}class Child extends Father{//func1(int i)是对func1()方法的一个重载//由于在父类中没有定义这个方法,所以它不能被父类类型的引用调用//所以在下面的main方法中child.func1(68)是不对的public void func1(int i){System.out.println("BBB");}//func2()重写了父类Father中的func2()方法//如果父类类型的引用中调用了func2()方法,那么必然是子类中重写的这个方法public void func2(){System.out.println("CCC");}}public class PolymorphismTest {public static void main(String[] args) {Father child = new Child();child.func1();//打印结果将会是什么?}}上面的程序是个很典型的多态的例子。
子类Child继承了父类Father,并重载了父类的func1()方法,重写了父类的func2()方法。
重载后的func1(int i)和func1()不再是同一个方法,由于父类中没有func1(int i),那么,父类类型的引用child就不能调用func1(int i)方法。
而子类重写了func2()方法,那么父类类型的引用child在调用该方法时将会调用子类中重写的func2()。
那么该程序将会打印出什么样的结果呢?很显然,应该是“CCC”。
对于多态,可以总结它为:一、使用父类类型的引用指向子类的对象;二、该引用只能调用父类中定义的方法和变量;三、如果子类中重写了父类中的一个方法,那么在调用这个方法的时候,将会调用子类中的这个方法;(动态连接、动态调用)四、变量不能被重写(覆盖),”重写“的概念只针对方法,如果在子类中”重写“了父类中的变量,那么在编译时会报错。
***************************************************************************************************** ***********************多态详解(整理)2008-09-03 19:29多态是通过:1 接口和实现接口并覆盖接口中同一方法的几不同的类体现的2 父类和继承父类并覆盖父类中同一方法的几个不同子类实现的.一、基本概念多态性:发送消息给某个对象,让该对象自行决定响应何种行为。
通过将子类对象引用赋值给超类对象引用变量来实现动态方法调用。
java 的这种机制遵循一个原则:当超类对象引用变量引用子类对象时,被引用对象的类型而不是引用变量的类型决定了调用谁的成员方法,但是这个被调用的方法必须是在超类中定义过的,也就是说被子类覆盖的方法。
1. 如果a是类A的一个引用,那么,a可以指向类A的一个实例,或者说指向类A的一个子类。
2. 如果a是接口A的一个引用,那么,a必须指向实现了接口A的一个类的实例。
二、Java多态性实现机制SUN目前的JVM实现机制,类实例的引用就是指向一个句柄(handle)的指针,这个句柄是一对指针:一个指针指向一张表格,实际上这个表格也有两个指针(一个指针指向一个包含了对象的方法表,另外一个指向类对象,表明该对象所属的类型);另一个指针指向一块从java堆中为分配出来内存空间。
三、总结1、通过将子类对象引用赋值给超类对象引用变量来实现动态方法调用。
DerivedC c2=new DerivedC();BaseClass a1= c2; //BaseClass 基类,DerivedC是继承自BaseClass的子类a1.play(); //play()在BaseClass,DerivedC中均有定义,即子类覆写了该方法分析:* 为什么子类的类型的对象实例可以覆给超类引用?自动实现向上转型。
通过该语句,编译器自动将子类实例向上移动,成为通用类型BaseClass;* a.play()将执行子类还是父类定义的方法?子类的。
在运行时期,将根据a这个对象引用实际的类型来获取对应的方法。
所以才有多态性。
一个基类的对象引用,被赋予不同的子类对象引用,执行该方法时,将表现出不同的行为。
在a1=c2的时候,仍然是存在两个句柄,a1和c2,但是a1和c2拥有同一块数据内存块和不同的函数表。
2、不能把父类对象引用赋给子类对象引用变量BaseClass a2=new BaseClass();DerivedC c1=a2;//出错在java里面,向上转型是自动进行的,但是向下转型却不是,需要我们自己定义强制进行。
c1=(DerivedC)a2; 进行强制转化,也就是向下转型.3、记住一个很简单又很复杂的规则,一个类型引用只能引用引用类型自身含有的方法和变量。
你可能说这个规则不对的,因为父类引用指向子类对象的时候,最后执行的是子类的方法的。
其实这并不矛盾,那是因为采用了后期绑定,动态运行的时候又根据型别去调用了子类的方法。
而假若子类的这个方法在父类中并没有定义,则会出错。
例如,DerivedC类在继承BaseClass中定义的函数外,还增加了几个函数(例如myFun())分析:当你使用父类引用指向子类的时候,其实jvm已经使用了编译器产生的类型信息调整转换了。
这里你可以这样理解,相当于把不是父类中含有的函数从虚拟函数表中设置为不可见的。
注意有可能虚拟函数表中有些函数地址由于在子类中已经被改写了,所以对象虚拟函数表中虚拟函数项目地址已经被设置为子类中完成的方法体的地址了。
4、Java与C++多态性的比较jvm关于多态性支持解决方法是和c++中几乎一样的,只是c++中编译器很多是把类型信息和虚拟函数信息都放在一个虚拟函数表中,但是利用某种技术来区别。
Java把类型信息和函数信息分开放。
Java中在继承以后,子类会重新设置自己的虚拟函数表,这个虚拟函数表中的项目有由两部分组成。
从父类继承的虚拟函数和子类自己的虚拟函数。
虚拟函数调用是经过虚拟函数表间接调用的,所以才得以实现多态的。
Java的所有函数,除了被声明为final的,都是用后期绑定。
四. 1个行为,不同的对象,他们具体体现出来的方式不一样,比如: 方法重载overloading 以及方法重写(覆盖)overrideclass Human{void run(){输出人在跑}}class Man extends Human{void run(){输出男人在跑}}这个时候,同是跑,不同的对象,不一样(这个是方法覆盖的例子)class Test{void out(String str){输出str}void out(int i){输出i}}这个例子是方法重载,方法名相同,参数表不同ok,明白了这些还不够,还用人在跑举例Human ahuman=new Man();这样我等于实例化了一个Man的对象,并声明了一个Human的引用,让它去指向Man这个对象意思是说,把Man这个对象当Human看了.比如去动物园,你看见了一个动物,不知道它是什么, "这是什么动物? " "这是大熊猫! "这2句话,就是最好的证明,因为不知道它是大熊猫,但知道它的父类是动物,所以,这个大熊猫对象,你把它当成其父类动物看,这样子合情合理.这种方式下要注意new Man();的确实例化了Man对象,所以ahuman.run()这个方法输出的是"男人在跑"如果在子类Man下你写了一些它独有的方法比如eat(),而Human没有这个方法,在调用eat方法时,一定要注意强制类型转换((Man)ahuman).eat(),这样才可以...对接口来说,情况是类似的...实例:package domatic;//定义超类superAclass superA {int i = 100;void fun(int j) {j = i;System.out.println("This is superA");}}// 定义superA的子类subBclass subB extends superA {int m = 1;void fun(int aa) {System.out.println("This is subB");}}// 定义superA的子类subCclass subC extends superA {int n = 1;void fun(int cc) {System.out.println("This is subC");}}class Test {public static void main(String[] args) {superA a = new superA();subB b = new subB();subC c = new subC();a = b;a.fun(100);a = c;a.fun(200);}}/** 上述代码中subB和subC是超类superA的子类,我们在类Test中声明了3个引用变量a, b,* c,通过将子类对象引用赋值给超类对象引用变量来实现动态方法调用。