多态的应用——数组多态

介绍

ai查询

在Java中,动态数组通常通过`ArrayList`类来实现,它是Java集合框架(Java Collections Framework)的一部分。`ArrayList`是一个可调整大小的数组实现,提供了比标准数组更多的灵活性和功能。
以下是使用`ArrayList`的一些基本示例代码:
### 创建一个动态数组(ArrayList)
```java
import java.util.ArrayList; // 导入ArrayList类
ArrayList<String> myList = new ArrayList<String>(); // 创建一个字符串类型的动态数组
```
### 向动态数组中添加元素
```java
myList.add("Apple"); // 添加元素
myList.add("Banana");
myList.add("Cherry");
```
### 访问动态数组中的元素
```java
String firstElement = myList.get(0); // 获取索引为0的元素
System.out.println("第一个元素是: " + firstElement);
```
### 修改动态数组中的元素
```java
myList.set(1, "Mango"); // 将索引为1的元素修改为"Mango"
```
### 删除动态数组中的元素
```java
myList.remove("Cherry"); // 删除指定的元素
myList.remove(0); // 删除索引为0的元素
```
### 获取动态数组的长度
```java
int size = myList.size(); // 获取动态数组的长度
System.out.println("动态数组的长度是: " + size);
```
### 遍历动态数组
```java
for (String item : myList) {
    System.out.println(item);
}
```
### 使用动态数组作为方法参数
```java
public void printArrayList(ArrayList<String> list) {
    for (String item : list) {
        System.out.println(item);
    }
}
```
### 动态数组的类型参数
`ArrayList`是泛型集合,可以存储任何类型的对象。例如,如果你想创建一个存储整数类型的动态数组,你可以这样做:
```java

ArrayList<Integer> myIntList = new ArrayList<Integer>();
myIntList.add(10); // 自动装箱(将int转换为Integer)
int number = myIntList.get(0); // 自动拆箱(将Integer转换为int)
```
这些示例展示了`ArrayList`的一些基本操作。在实际应用中,`ArrayList`提供了更多高级功能和用法,您可以根据具体需求来使用它们。
 

我们这里创造三个类。person,student类,teacher类

person类

package hansunping;
public class person{
	private String name;
	public int age;
	public person(String name,int age) {
		// TODO Auto-generated constructor stub
		this.name=name;
		this.age=age;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String say() {//返回名字年龄
		return name+"\t"+age;
		
	}
	
}

在您提供的代码中,`Person` 类是一个简单的Java类,它具有以下特点:
1. **私有属性**:`Person` 类有两个私有属性 `name` 和 `age`,这些属性用于存储人的名字和年龄。
2. **构造函数**:`Person` 类有一个构造函数,它接受两个参数 `name` 和 `age`,并使用这些参数来初始化对象的属性。
3. **公共的 Getter 和 Setter 方法**:`Person` 类为 `name` 和 `age` 属性提供了公共的 Getter 和 Setter 方法。这些方法允许外部代码读取和修改 `Person` 对象的 `name` 和 `age` 属性。
4. **say 方法**:`Person` 类有一个名为 `say` 的方法,它返回一个包含 `name` 和 `age` 属性值的字符串。这个方法可以用来输出一个人的基本信息。
5. **继承**:`Person` 类被设计为可以被其他类继承。在您的代码中,`Student` 和 `Teacher` 类都继承自 `Person` 类。
6. **多态性**:由于 `Student` 和 `Teacher` 类继承自 `Person` 类,它们可以使用 `Person` 类的引用变量。在Java中,这体现了多态性,即子类对象可以被视为父类对象,但仍然保留了子类的特性。
在您的 `main` 方法中,您创建了一个 `Person` 类型的数组 `persons`,并填充了不同类型的对象(`Person`、`Student` 和 `Teacher`)。当您遍历这个数组并调用每个元素的 `say` 方法时,Java虚拟机会根据对象的实际类型来调用相应的 `say` 方法,这展示了多态性的运行时绑定特性。
如果您想要查看 `Person` 类的具体实现,请提供 `Person` 类的完整代码,我可以为您提供更详细的分析。
 

student类

package hansunping;

public class student extends person {
	private String name;
	public int age;
	private double score;
	public double getScore() {
		return score;
	}
	public void setScore(double score) {
		this.score = score;
	}
	public student( String name,int age, double score) {
		// TODO Auto-generated constructor stub
		super(name, age);
		this.score=score;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	@Override//重写父类say方法
	public String say() {//返回名字年龄
		return super.say()+"scor="+score;
		
	}
}

根据您之前提供的 `Student` 类的代码,`Student` 类是 `Person` 类的子类。它继承了 `Person` 类的所有属性和方法,并添加了一些额外的属性和方法来表示学生的特定信息。以下是 `Student` 类的基本结构和特点:
```java
package hansunping;
public class Student extends Person {
    private double score;
    public Student(String name, int age, double score) {
        super(name, age); // 调用父类的构造函数
        this.score = score; // 初始化score属性
    }
    public double getScore() {
        return score;
    }
    public void setScore(double score) {
        this.score = score;
    }
    // 重写父类的say方法
    @Override
    public String say() {
        return super.say() + " score=" + score;
    }
}
```
1. **继承**:`Student` 类通过 `extends` 关键字继承自 `Person` 类。这意味着 `Student` 类继承了 `Person` 类的所有公共和保护的属性和方法。
2. **额外的属性**:`Student` 类添加了一个新的私有属性 `score`,用于存储学生的分数。
3. **构造函数**:`Student` 类有一个构造函数,它接受三个参数 `name`、`age` 和 `score`。构造函数首先调用父类 `Person` 的构造函数来初始化 `name` 和 `age` 属性,然后初始化 `score` 属性。
4. **公共的 Getter 和 Setter 方法**:`Student` 类为 `score` 属性提供了公共的 Getter 和 Setter 方法,允许外部代码读取和修改学生的分数。
5. **方法重写**:`Student` 类重写了 `Person` 类的 `say` 方法。在 `Student` 类的 `say` 方法中,首先调用了 `super.say()` 来获取父类的 `say` 方法的输出,然后添加了学生的分数信息。
通过继承和重写,`Student` 类能够扩展 `Person` 类的功能,以包括学生的特定信息。这样,`Student` 对象既可以作为 `Person` 对象使用,也可以使用 `Student` 类的额外功能。

teacher类

package hansunping;

public class student extends person {
	private String name;
	public int age;
	private double score;
	public double getScore() {
		return score;
	}
	public void setScore(double score) {
		this.score = score;
	}
	public student( String name,int age, double score) {
		// TODO Auto-generated constructor stub
		super(name, age);
		this.score=score;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	@Override//重写父类say方法
	public String say() {//返回名字年龄
		return super.say()+"scor="+score;
		
	}
}

您之前没有提供 `Teacher` 类的代码,但我可以根据您的描述和通常的编程实践来给您一个 `Teacher` 类的基本示例。假设 `Teacher` 类也继承自 `Person` 类,并且有一个额外的属性来表示教师的工资。以下是 `Teacher` 类的一个可能的实现:
```java
package hansunping;
public class Teacher extends Person {
    private double salary;
    public Teacher(String name, int age, double salary) {
        super(name, age); // 调用父类的构造函数
        this.salary = salary; // 初始化salary属性
    }
    public double getSalary() {
        return salary;
    }
    public void setSalary(double salary) {
        this.salary = salary;
    }
    // 重写父类的say方法
    @Override
    public String say() {
        return super.say() + " salary=" + salary;
    }
}
```
在这个示例中,`Teacher` 类具有以下特点:
1. **继承**:`Teacher` 类通过 `extends` 关键字继承自 `Person` 类,这意味着它继承了 `Person` 类的所有公共和保护的属性和方法。
2. **额外的属性**:`Teacher` 类添加了一个新的私有属性 `salary`,用于存储教师的工资。
3. **构造函数**:`Teacher` 类有一个构造函数,它接受三个参数 `name`、`age` 和 `salary`。构造函数首先调用父类 `Person` 的构造函数来初始化 `name` 和 `age` 属性,然后初始化 `salary` 属性。
4. **公共的 Getter 和 Setter 方法**:`Teacher` 类为 `salary` 属性提供了公共的 Getter 和 Setter 方法,允许外部代码读取和修改教师的工资。
5. **方法重写**:`Teacher` 类重写了 `Person` 类的 `say` 方法。在 `Teacher` 类的 `say` 方法中,首先调用了 `super.say()` 来获取父类的 `say` 方法的输出,然后添加了教师的工资信息。
通过这种方式,`Teacher` 类能够扩展 `Person` 类的功能,以包括教师的特定信息。这样,`Teacher` 对象既可以作为 `Person` 对象使用,也可以使用 `Teacher` 类的额外功能。

主类

package hansunping;

public class demon1 {
	public static void main(String[] args) {
			person[] persons=new person[5];//你尝试创建一个名为 persons 的 Person 类型数组,该数组有5个元素:
			persons[0]=new person("jack", 20);
			persons[1]=new student("jack", 20,100);
			persons[2]=new student("smith", 18,30.1);
			persons[3]=new teacher("scott", 30,2000);
			persons[4]=new teacher("king", 30,2000);
			//循环遍历数组。调用say
			
			for (int i = 0; i < persons.length; i++) {
				
				System.out.println(persons[i].say());//动态绑定
			}
	        //、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、
	        //如果我们将student类的say()方法注销,他寻找student类的say方法无果后,会再向它的父类调用say方法。返回我是人类,效果等同于
	
	}

}

您之前提供的 `demon1` 类是一个包含 `main` 方法的类,它演示了多态性的概念。在 `main` 方法中,您创建了一个 `Person` 类型的数组 `persons`,并填充了不同类型的对象(`Person`、`Student` 和 `Teacher`)。然后,您遍历这个数组并调用每个元素的 `say` 方法,这展示了多态性的运行时绑定特性。
以下是 `demon1` 类的代码示例,包括 `main` 方法中的内容:
```java
package hansunping;
public class Demon1 {
    public static void main(String[] args) {
        Person[] persons = new Person[5]; // 创建一个Person类型的数组
        persons[0] = new Person("Jack", 20);
        persons[1] = new Student("Jack", 20, 100);
        persons[2] = new Student("Smith", 18, 30.1);
        persons[3] = new Teacher("Scott", 30, 2000);
        persons[4] = new Teacher("King", 35, 2500);
        // 循环遍历数组,调用say方法
        for (int i = 0; i < persons.length; i++) {
            System.out.println(persons[i].say()); // 动态绑定
        }
    }
}
```
在这个示例中,`demon1` 类的 `main` 方法执行了

以下操作:
1. 创建了一个 `Person` 类型的数组 `persons`,长度为5。
2. 使用不同的构造函数填充数组,创建了 `Person`、`Student` 和 `Teacher` 的实例。
3. 通过循环遍历数组,并调用每个元素的 `say` 方法。由于 `Student` 和 `Teacher` 类都重写了 `Person` 类的 `say` 方法,因此调用 `say` 方法时会根据对象的实际类型来调用相应的方法。
4. 输出每个对象的 `say` 方法的返回值,这会显示每个对象的特定信息。
这个示例展示了多态性的一个关键特性:调用哪个方法是在运行时根据对象的实际类型决定的,而不是根据引用变量的类型决定的。这就是所谓的动态绑定。

特点

您提供的 `Person[] persons = new Person[5];` 语句创建了一个 `Person` 类型的数组,具有以下特点:
1. **类型指定**:这个语句指定了数组的类型为 `Person[]`,这意味着数组可以存储 `Person` 类的对象。
2. **数组长度**:数组的长度被指定为5,这意味着数组可以存储5个 `Person` 类型的对象。
3. **内存分配**:在堆内存中为这个数组分配了5个 `Person` 对象的内存空间。数组中的每个元素都是 `Person` 类型的引用变量,默认初始化为 `null`。
4. **初始化**:数组创建后,数组中的每个元素都默认初始化为 `null`。这意味着在数组创建时,数组中并没有实际的 `Person` 对象,只有存储对象的内存空间。
5. **可变性**:数组的大小在创建后是固定的,无法改变。这意味着一旦创建了数组,就不能再增加或减少数组的大小。
6. **多态性**:由于 `Student` 和 `Teacher` 类继承自 `Person` 类,你可以将 `Student` 或 `Teacher` 类的对象赋值给 `Person` 类型的数组。这是因为 `Student` 和 `Teacher` 类的对象在运行时可以被视为 `Person` 类的对象。
7. **动态绑定**:当你调用数组中某个元素的 `say` 方法时,实际上会调用该元素所引用对象的 `say` 方法。这体现了多态性的动态绑定特性,即调用哪个方法取决于运行时对象的类型。
总结来说,`Person[] persons = new Person[5];` 语句创建了一个可以存储5个 `Person` 对象引用的数组,每个元素默认初始化为 `null`。这个数组可以存储 `Person`、`Student` 或 `Teacher` 类的对象,并且能够体现多态性的动态绑定特性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值