java多态性
- 格式:doc
- 大小:70.00 KB
- 文档页数:9
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】⾯向对象的四个基本特征:唯⼀性、分类性、继承性
和多态性
1.唯⼀性
唯⼀性是指每个对象都是唯⼀的,具有唯⼀标识符。
在对象的整个⽣命周期中,标识符是⼀成不变的,系统可通过该标识符,在内存中找到相应对象。
2.分类性
分类性是指将具有⼀致属性和⾏为的对象抽象成类,只保留与应⽤有关的性质,其他内容忽略。
任何类的划分都是主观的,但必须与具体应⽤有关。
3.继承性
继承性是指⼦类⾃动继承⽗类的属性和⽅法,并且可以在⽗类的基础上加⼊若⼲新内容。
例如,“⼈”这个类抽象了这个群体的基本特征,⽽“学⽣”和“⽼师”除了具备“⼈”所定义的基础特性外,各⾃⼜具有各⾃的新特性。
继承性是⾯向对象程序设计语⾔不同于其他语⾔的最重要特点。
通过类的继承,可使公共的特性能够共享,提⾼代码的可重⽤性、减少冗余,同时简化了对象、类的创建⼯作,规范了类的等级结构。
4.多态性
多态性是指不同对象,在收到同⼀消息后,可产⽣不同结果,具有不同表现⾏为。
多态性允许每个对象以⾃⾝的⽅法去响应共同消息,以此增强软件的灵活性和可重⽤性。
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多态的笔试题。
请注意,以下问题仅供参考。
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面试题1. 什么是Java虚拟机(JVM)?Java虚拟机(JVM)是Java程序的运行环境,它是一个虚拟的计算机,它可以在不同的操作系统上运行Java程序。
JVM负责将Java程序编译后的字节码解释成机器码,并执行程序。
2. 什么是Java的多态性?Java的多态性是指同一个方法可以在不同的对象上产生不同的行为。
这是通过继承和接口实现的。
多态性可以提高代码的可重用性和可扩展性。
3. 什么是Java的封装性?Java的封装性是指将数据和方法封装在一个类中,只对外暴露必要的接口,隐藏实现细节。
这可以提高代码的安全性和可维护性。
4. 什么是Java的继承性?Java的继承性是指一个类可以继承另一个类的属性和方法。
这可以提高代码的可重用性和可扩展性。
5. 什么是Java的抽象类?Java的抽象类是一种不能被实例化的类,它只能被继承。
抽象类可以包含抽象方法和非抽象方法,抽象方法必须在子类中被实现。
6. 什么是Java的接口?Java的接口是一种抽象类型,它只包含方法的声明,没有方法的实现。
接口可以被类实现,一个类可以实现多个接口。
接口可以提高代码的可重用性和可扩展性。
7. 什么是Java的异常?Java的异常是指程序运行时发生的错误或异常情况。
Java提供了一些异常类,可以用来处理不同类型的异常。
异常处理可以提高程序的健壮性和可靠性。
8. 什么是Java的线程?Java的线程是指程序中的一条执行路径,它可以独立运行,可以与其他线程并发执行。
Java提供了多线程编程的支持,可以提高程序的并发性和性能。
9. 什么是Java的反射?Java的反射是指在程序运行时动态获取类的信息和调用类的方法。
Java提供了反射机制,可以在运行时获取类的信息,创建对象,调用方法等。
反射可以提高程序的灵活性和可扩展性。
10. 什么是Java的注解?Java的注解是一种元数据,它可以用来描述类、方法、变量等元素的属性和行为。
尚硅谷面试题尚硅谷是一家知名的IT培训机构,提供高质量的编程教育和就业服务。
作为一名学员或者准备面试的应聘者,了解尚硅谷的面试题目是非常重要的。
本文将为大家介绍几道尚硅谷的常见面试题,并且给出详细的解答和思路分析。
面试题一:谈谈Java中的多态性?思路分析:多态性是面向对象编程的重要特性之一,也是Java语言中常见的面试题目。
多态性通过继承和接口实现,实现了父类引用可以指向子类对象的特点。
在面试中,可以从多个角度来回答这个问题,包括多态的定义、实现方式、优点和应用场景等。
解答:多态性是指同一类型的变量,在不同的对象实例上表现出不同的行为。
在Java中,多态性通过继承和接口实现。
通过继承,我们可以定义一个父类,然后派生出多个子类,这些子类都拥有父类的属性和方法。
通过接口,我们可以定义一组规范,然后多个类实现这个接口,根据实现类的不同,调用相同的接口方法会得到不同的结果。
多态性的主要优点是增加代码的灵活性和可扩展性。
通过使用父类引用指向不同的子类对象,我们可以在运行时动态地选择调用哪个子类的方法,从而实现了代码的灵活性。
另外,当需要添加新的子类时,我们只需要继承或者实现相同的父类或接口,而不需要修改原有的代码,从而实现了代码的可扩展性。
多态性适用于很多场景,比如通过一个统一的接口来操作不同的实现类,实现代码的解耦和通用性;通过将子类对象当作父类对象使用,提高代码的灵活性和可维护性等。
但是需要注意,在进行多态操作时,需要保证父类引用指向的对象是其子类对象,否则会出现类型转换异常。
面试题二:谈谈Java中的异常处理机制?思路分析:异常处理是Java编程的重要部分,良好的异常处理能够提高程序的健壮性和容错性。
在面试中,可以从异常的概念和分类、处理方法、异常处理的最佳实践等方面来回答这个问题。
解答:在Java中,异常是指程序在运行时遇到的意外事件或错误条件。
异常分为受检异常(Checked Exception)和非受检异常(Unchecked Exception)。
java中级工程师面试题1. 面试题:请简述Java中的多态性以及其实现方式。
Java中的多态性是指同一类型的对象在不同的情况下可以表现出不同的行为。
实现多态性的方式有两种:静态多态和动态多态。
静态多态指的是方法的重载,即在同一个类中可以定义多个方法名相同但参数列表不同的方法。
在程序调用该方法时,编译器会根据传入的参数类型和数量选择合适的方法执行。
动态多态指的是方法的重写,即在父类和子类之间存在同名同参数列表的方法,子类可以根据自己的需求重新定义该方法的实现。
在程序运行时,根据对象的实际类型来确定调用哪个方法,实现动态绑定。
2. 面试题:请解释Java中的封装性以及其作用。
Java中的封装性是指将类的属性、方法封装在类的内部,对外部隐藏具体实现细节,只提供必要的接口进行访问。
封装的作用有两个方面:一是增强了代码的可维护性和可扩展性,将实现细节隐藏起来,只暴露必要的接口给外部使用,当内部实现发生变化时,不会影响外部使用该类的代码;二是提高了代码的安全性,封装可以防止外部直接对属性进行修改,只能通过类提供的方法进行访问和修改,可以对输入进行合法性检查和控制,确保数据的有效性和安全性。
3. 面试题:请描述Java中的继承关系,以及继承的优缺点。
Java中的继承是指一个类可以从另一个类中继承属性和方法,被继承的类称为父类或超类,继承的类称为子类或派生类。
继承的优点:- 代码复用:子类可以继承父类的属性和方法,减少了代码的重复编写。
- 可扩展性:子类可以在继承的基础上进行扩展,添加新的属性和方法,增加了代码的灵活性和可扩展性。
- 统一接口:子类可以通过继承获得父类的公共接口,使得代码更加简洁清晰,易于理解和维护。
继承的缺点:- 破坏封装性:子类可以访问父类的非私有成员,破坏了父类的封装性,可能导致不安全因素的引入。
- 子类与父类的耦合度高:子类与父类之间形成了较强的耦合关系,一旦修改了父类的实现,可能会影响到所有的子类。
java多态实验报告Java多态实验报告引言:Java是一种面向对象的编程语言,多态是其核心特性之一。
本实验旨在通过编写代码并运行实验,深入理解Java中的多态概念和使用方法。
实验目的:1. 理解多态的概念和原理;2. 掌握多态的使用方法和技巧;3. 通过实验加深对多态的理解和应用。
实验步骤:1. 创建一个抽象类Animal,并定义一个抽象方法makeSound();2. 创建两个继承自Animal的子类:Dog和Cat,并分别实现makeSound()方法;3. 在主函数中创建一个Animal类型的数组,包含两个元素,分别为Dog和Cat 的实例;4. 遍历数组,调用每个元素的makeSound()方法;5. 运行程序,观察输出结果。
实验结果:通过运行实验代码,我们可以看到Dog和Cat的实例都调用了makeSound()方法,但输出的结果却不同。
这就是多态的体现。
多态性允许我们在父类Animal的引用下,调用子类Dog和Cat的方法,实现了代码的灵活性和扩展性。
实验分析:1. 多态的概念:多态是指同一种类型的对象,在不同的情况下表现出不同的行为。
在本实验中,Dog和Cat都是Animal的子类,它们都继承了makeSound()方法,但实现方式不同,因此在调用时会表现出不同的行为。
2. 多态的原理:多态的实现依赖于继承和方法重写。
通过将子类对象赋值给父类引用,实现了对子类对象的调用。
在运行时,会根据实际对象的类型来确定调用哪个方法。
3. 多态的优势:多态使代码更加灵活和可扩展。
当需要新增一种动物时,只需创建一个新的子类并实现makeSound()方法,不需要修改原有的代码,即可实现新增功能。
4. 多态的应用场景:多态常用于面向对象的设计和开发中,尤其是在需要处理多种类型对象的情况下。
通过使用多态,可以简化代码结构,提高代码的可读性和可维护性。
实验总结:通过本次实验,我深入理解了Java中的多态概念和使用方法。
java 多态选择题一、单选题1. 多态性的基础是()。
A. 继承B. 接口C. 抽象类D. 方法重写答案是:D. 方法重写。
多态性是指不同对象对同一消息有不同的响应,在Java中,可以通过方法重写来实现多态性。
2. 下列哪个选项不是多态的特性()。
A. 方法重载B. 参数传递C. 向上转型D. 向下转型答案是:A. 方法重载。
多态性包括方法重载和参数传递等特性,向上转型和向下转型是多态的体现形式之一。
3. 在Java中,实现多态的方式有()。
A. 继承和接口B. 继承和抽象类C. 继承和接口,抽象类都有用D. 类直接实现接口答案是:A. 继承和接口。
在Java中,实现多态的方式有两种:继承和接口。
向上转型和向下转型也是多态的体现形式。
4. 关于接口和多态的关系,以下说法正确的是()。
A. 接口不能被实例化,只能被继承B. 接口可以用来实现多态,但不能通过接口引用实现多态的类对象C. 实现多态的类必须实现接口的所有方法D. 以上说法都不对答案是:D. 以上说法都不对。
接口可以用来实现多态,可以通过接口引用实现多态的类对象,实现多态的类不一定需要实现接口的所有方法。
5. 在Java中,以下哪个关键字用于实现多态()。
A. extends 和 implementsB. extends 和 finalC. extends 和 interfaceD. override 和 extends答案是:D. override 和 extends。
Java中,关键字override和extends用于实现多态。
override用于子类重写父类的方法,extends用于继承父类的接口或抽象类。
二、多选题1. 多态性的表现形式有()等。
A. 向上转型B. 向下转型C. 方法重载D. 方法重写E. 参数传递答案是:ADE。
多态性的表现形式包括向上转型、向下转型、方法重载和方法重写,也涉及到参数传递等特性。
2. 下列哪些选项体现了Java中的多态性()A. 子类对象替换父类对象B. 使用父类的引用指向子类对象C. 使用接口引用指向实现了该接口的类对象D. 使用方法重载实现多态性答案是:ABCD。
java 中级面试题一、Java中的基本概念Java是一门广泛应用于软件开发领域的高级编程语言,由Sun Microsystems公司于1995年发行。
它具有跨平台的特性,能够在不同的操作系统上运行,如Windows、Linux和Mac OS等。
Java的设计宗旨是“一次编写,到处运行”,因此它成为了许多开发人员的首选语言。
Java面试过程中,会涉及到一些中级的知识点和题目,下面我们将逐一介绍并讨论。
二、面试题目一:Java中的多态性是什么?面试官通常会问到Java中的多态性概念,因为多态性是面向对象编程的重要特性之一。
在Java中,多态性指的是同一个类的实例在不同的情况下表现出不同的行为。
这是通过方法的重载和方法的重写两种方式来实现的。
1. 方法的重载(Overloading):在同一个类中,可以定义多个具有相同名称但参数列表不同的方法。
这样在调用方法时,可以根据传入的参数类型和个数,自动选择调用相应的方法。
例如:```javapublic class Demo {public void print(String str) {System.out.println("String: " + str);}public void print(int num) {System.out.println("Number: " + num);}public static void main(String[] args) {Demo demo = new Demo();demo.print("Hello");demo.print(123);}}```输出结果为:```String: HelloNumber: 123```2. 方法的重写(Overriding):在类的继承关系中,子类可以重写父类中已有的方法,以实现子类特定的功能需求。
子类重写的方法具有相同的名称、参数列表和返回类型。
列举java中多态的体现多态是面向对象编程中的一个重要概念,它允许不同的对象对同一消息做出不同的响应。
在Java中,多态性是通过继承和接口实现来实现的。
下面将列举Java中多态的体现。
一、方法重载方法重载是指在同一个类中定义了两个或两个以上名称相同但参数类型或个数不同的方法。
这种情况下,当调用该方法时,编译器会根据参数类型和个数来判断应该调用哪个方法。
这种方式就是Java中最基本的多态性体现。
二、方法覆盖方法覆盖是指子类重新定义了父类中已有的方法,并且子类和父类中该方法具有相同的名称、返回值类型和参数列表。
当使用父类引用变量引用子类对象时,调用该方法时会自动调用子类中定义的那个方法,而不是父类中定义的那个方法。
三、向上转型向上转型是指将子类对象赋值给父类引用变量。
这种情况下,可以通过父类引用变量来访问子类对象中继承自父类的成员变量和成员方法。
由于向上转型后只能访问到父类中定义的成员变量和成员方法,因此无法直接访问子类中定义的成员变量和成员方法。
四、动态绑定动态绑定是指在运行时根据对象的实际类型来确定调用哪个方法。
在Java中,所有的非私有方法都是动态绑定的,也就是说,当调用一个非私有方法时,编译器不会确定要调用哪个方法,而是等到运行时才根据对象的实际类型来确定要调用哪个方法。
五、抽象类和接口抽象类和接口也是Java中多态性的体现。
抽象类和接口都定义了一些规范,而具体实现则由子类来完成。
当使用父类引用变量引用子类对象时,可以通过父类引用变量来访问子类对象中实现了父类或接口中定义的规范的成员变量和成员方法。
六、多态数组多态数组是指数组中存储的元素可以是不同类型的对象。
在Java中,可以使用Object类型来定义一个多态数组,在运行时将不同类型的对象存储到该数组中。
由于Object类型是所有类型的父类,因此可以使用父类引用变量来访问存储在数组中的不同类型的对象。
七、泛型泛型也是Java中多态性的一种体现方式。
中级java工程师面试题一、概述Java是一种高级编程语言,广泛应用于企业级应用开发。
中级Java 工程师负责设计、开发和维护Java应用程序,需要具备扎实的编程基础、深入的Java知识和相关的技术经验。
以下是一些中级Java工程师常见的面试题,旨在评估应聘者的技能和能力。
二、面试题目1. 请解释Java中的封装性是什么?封装是Java面向对象编程的核心概念之一。
它通过将数据和行为封装在一个类中,保护数据不被外部直接访问和修改,只能通过类的方法来间接操作。
封装可以提高代码的复用性、可维护性和安全性。
2. 什么是Java中的多态性?多态是指同一个类的对象在不同的情况下可以表现出不同的行为。
它通过方法的重写和重载实现。
多态可以提高代码的灵活性和可扩展性,使得程序结构更加清晰。
3. 请解释Java中的继承和实现接口的区别是什么?继承是指一个类继承另一个类的属性和方法,可以通过继承实现代码的重用。
实现接口是指一个类实现了某个接口,并需要实现接口中的方法。
继承是类之间的关系,实现接口是类与接口之间的关系。
4. 请解释Java中的异常处理是什么?异常处理是指在程序执行过程中出现错误或异常情况时,通过捕获并处理异常来保证程序的正常运行。
Java中的异常可以分为检查异常和非检查异常,处理异常可以使用try-catch语句块来捕获并处理异常。
5. 请解释Java中的线程是什么?如何创建和控制线程?线程是指一个程序中的执行流程,可以并发执行多个线程。
在Java 中,可以通过继承Thread类或实现Runnable接口来创建线程。
控制线程可以使用线程的start()方法启动线程、sleep()方法暂停线程、join()方法等待其他线程执行完毕。
6. 请解释Java中的同步和异步的区别是什么?同步是指多个线程在执行过程中按照一定的顺序线性执行,一个线程的执行结果依赖于前一个线程的结果。
异步是指多个线程同时执行,各自独立地进行任务,不需要等待其他线程的结果。
同方计算机面试题及答案一、介绍同方计算机是一家知名的信息技术企业,拥有广泛的产品线和服务,涵盖了软硬件研发、系统集成、解决方案等领域。
该公司在大数据、人工智能、云计算等技术上处于领先地位,广受行业认可。
本文将为大家介绍一些同方计算机的面试题目及答案。
二、面试题目及答案1. 什么是Java中的多态性?如何实现多态性?答:Java中的多态性是指同一操作可以应用于多个不同类型的对象,且能够产生不同的结果。
在Java中实现多态性需要使用继承和方法重写。
子类继承父类后,可以重写父类的方法,然后通过父类的引用指向子类的对象,从而实现多态性。
2. 请解释Java中的final关键字的作用。
答:final关键字可以用于修饰类、方法和变量。
当用final修饰类时,表明该类不能被继承;当用final修饰方法时,表明该方法不能被子类重写;当用final修饰变量时,表示该变量的值不能被修改。
3. 简述Java中的异常处理机制及其使用场景。
答:Java中的异常处理机制是通过try-catch语句块来实现的。
当可能发生异常的代码放置在try块中,如果发生异常,则根据异常类型执行相应的catch块中的代码。
异常处理机制的使用场景包括处理输入错误、网络错误和文件操作等可能会发生的异常情况。
4. 请介绍一下HashMap和HashTable的区别。
答:HashMap和HashTable都是用于存储键值对的数据结构,但有以下区别:首先,HashMap是非线程安全的,而HashTable是线程安全的;其次,HashMap允许键和值都为null,而HashTable不允许;最后,HashMap的性能通常优于HashTable。
5. 什么是单例模式?请给出一个实现单例模式的示例代码。
答:单例模式是一种创建型设计模式,它确保一个类只有一个实例,并提供一个全局访问点。
以下是一个实现单例模式的示例代码:```javapublic class Singleton {private static Singleton instance;private Singleton() {}public static synchronized Singleton getInstance() {if (instance == null) {instance = new Singleton();}return instance;}}```以上代码中,通过私有的构造方法限制了其他类对该类的实例化,通过getInstance()方法返回唯一的实例,保证了单例。
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,通过将子类对象引用赋值给超类对象引用变量来实现动态方法调用。