Java语言里什么叫做多态?多态编写的程序会不会造成内存的占用?多态和多对象是一个意思么?
【以下回答由 GPT 生成】
回答:
Java语言中的多态是指一个对象变量可以引用不同类型的对象,并根据对象类型的不同而表现出不同的行为。具体来说,多态性允许我们使用父类引用来引用子类对象,并在运行时动态地确定最终使用的方法。这样可以提高代码的灵活性和可扩展性。
在Java中实现多态有两个必要条件:继承和重写。我们需要定义一个父类,然后通过继承创建子类,子类可以使用父类的方法并且可以重写这些方法来实现多态。
多态编写的程序不会造成额外的内存占用。实际上,多态性可以帮助我们节省内存,因为我们可以通过多态性实现用更少的代码来处理不同类型的对象。多态性实现的方式是使用指向子类对象的父类引用,而不需要创建子类对象。
多对象是指可以创建多个对象,每个对象都有自己的属性和方法。多对象与多态性不是同一个概念。多对象是通过创建不同的对象来实现多个实例,每个对象都是独立的,有自己独立的内存空间。而多态性是同一个引用指向不同类型的对象,同一个引用可以根据实际指向的对象类型的不同,表现出不同的行为。
总结起来,多态性是Java语言中的一个重要概念,它允许我们使用父类引用来引用子类对象,并根据对象类型的不同而表现出不同的行为。多态性编写的程序不会造成额外的内存占用,它可以提高代码的灵活性和可扩展性。而多对象是指可以创建多个对象,每个对象都有自己的属性和方法,是与多态性不同的概念。
【相关推荐】
多态是指,子类可以替换父类,在实际的代码运行过程中,调用子类的方法实现,实现多态的方式有三种,继承、接口类以及duck-typing
创建一个动态数组,以及一个排序的动态数组子类来看看多态的特性:
package com.example.designpattern;
/**
* 动态数组
* @author tianmaolin
*/
public class DynamicArray {
private static final int DEFAULT_CAPACITY = 10;
/**
* The Size.
*/
protected int size = 0;
/**
* The Capacity.
*/
protected int capacity = DEFAULT_CAPACITY;
/**
* The Elements.
*/
protected Integer[] elements = new Integer[DEFAULT_CAPACITY];
/**
* Size int.
*
* @return the int
*/
public int size() { return this.size; }
/**
* Get integer.
*
* @param index the index
* @return the integer
*/
public Integer get(int index) { return elements[index];}
//...省略n多方法...
/**
* Add.
*
* @param e the e
*/
public void add(Integer e) {
ensureCapacity();
elements[size++] = e;
}
/**
* Ensure capacity.
*/
protected void ensureCapacity() {
//...如果数组满了就扩容...代码省略...
}
}
/**
* 排序动态数组
* @author tianmaolin
*/
class SortedDynamicArray extends DynamicArray {
@Override
public void add(Integer e) {
ensureCapacity();
int i;
for (i = size-1; i>=0; --i) { //保证数组中的数据有序
if (elements[i] > e) {
elements[i+1] = elements[i];
} else {
break;
}
}
elements[i+1] = e;
++size;
}
}
/**
1. 测试排序
2. @author tianmaolin
*/
class Test {
/**
* Test.
*
* @param dynamicArray the dynamic array
*/
public static void test(DynamicArray dynamicArray) {
dynamicArray.add(5);
dynamicArray.add(1);
dynamicArray.add(3);
for (int i = 0; i < dynamicArray.size(); ++i) {
System.out.println(dynamicArray.get(i));
}
}
/**
* Main.
*
* @param args the args
*/
public static void main(String args[]) {
DynamicArray dynamicArray = new SortedDynamicArray();
test(dynamicArray); // 打印结果:1、3、5
}
}
多态这种特性也需要编程语言提供特殊的语法机制来实现。在上面的例子中,我们用到了三个语法机制来实现多态。
通过这三种语法机制配合在一起,我们就实现了在 test() 方法中,子类 SortedDyamicArray 替换父类 DynamicArray,执行子类 SortedDyamicArray 的 add() 方法,也就是实现了多态特性。当然除了继承的方式(无论是继承的普通类还是抽象类)
还可以使用接口的方式实现多态:
public interface Iterator {
boolean hasNext();
String next();
String remove();
}
public class Array implements Iterator {
private String[] data;
public boolean hasNext() { ... }
public String next() { ... }
public String remove() { ... }
//...省略其他方法...
}
public class LinkedList implements Iterator {
private LinkedListNode head;
public boolean hasNext() { ... }
public String next() { ... }
public String remove() { ... }
//...省略其他方法...
}
public class Demo {
private static void print(Iterator iterator) {
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
}
public static void main(String[] args) {
Iterator arrayIterator = new Array();
print(arrayIterator);
Iterator linkedListIterator = new LinkedList();
print(linkedListIterator);
}
}
在这段代码中,Iterator 是一个接口类,定义了一个可以遍历集合数据的迭代器。Array 和 LinkedList 都实现了接口类 Iterator。我们通过传递不同类型的实现类(Array、LinkedList)到 print(Iterator iterator) 函数中,支持动态的调用不同的 next()、hasNext() 实现。
扩展一下,虽然Java这样的语言目前不支持duck-typing实现多态,多多少少也可以了解一下,一段python代码:
class Logger:
def record(self):
print(“I write a log into file.”)
class DB:
def record(self):
print(“I insert data into db. ”)
def test(recorder):
recorder.record()
def demo():
logger = Logger()
db = DB()
test(logger)
test(db)
从这段代码中,我们发现,duck-typing 实现多态的方式非常灵活。Logger 和 DB 两个类没有任何关系,既不是继承关系,也不是接口和实现的关系,但是只要它们都有定义了 record() 方法,就可以被传递到 test() 方法中,在实际运行的时候,执行对应的 record() 方法。也就是说,只要两个类具有相同的方法,就可以实现多态,并不要求两个类之间有任何关系,这就是所谓的 duck-typing,是一些动态语言所特有的语法机制。而像 Java 这样的静态语言,通过继承实现多态特性,必须要求两个类之间有继承关系,通过接口实现多态特性,类必须实现对应的接口
多态特性能提高代码的可扩展性和复用性
print()
函数就可以实现遍历打印不同类型(Array、LinkedList)集合的数据。当再增加一种要遍历打印的类型的时候,比如 HashMap,我们只需让 HashMap 实现 Iterator 接口,重新实现自己的 hasNext()、next() 等方法就可以了,完全不需要改动 print() 函数的代码。所以说,。除此之外,多态也是很多设计模式、设计原则、编程技巧的代码实现基础,比如策略模式、基于接口而非实现编程、依赖倒置原则、里式替换原则、利用多态去掉冗长的 if-else 语句等