MST

星途 面试题库

面试题:Kotlin泛型变型与集合操作

假设有一个类`Animal`及其子类`Dog`和`Cat`。定义一个泛型函数`addAnimals`,该函数接收一个`MutableList<out Animal>`类型的参数,向这个列表中添加一个`Dog`实例和一个`Cat`实例。分析该操作是否可行,如果不可行,如何修改代码实现类似功能。请写出代码及分析过程。
22.8万 热度难度
编程语言Kotlin

知识考点

AI 面试

面试题答案

一键面试
  1. 分析该操作是否可行
    • 当函数接收MutableList<out Animal>类型的参数时,out关键字表示协变。这意味着这个列表可以安全地读取Animal类型或其子类型(如DogCat)的元素,但不能写入(除了null)。因为写入操作可能破坏类型安全,例如,如果这个列表实际指向的是MutableList<Dog>,写入Cat实例就会导致类型错误。所以直接向MutableList<out Animal>中添加DogCat实例是不可行的。
  2. 修改代码实现类似功能
    • 一种可行的方法是将参数类型改为MutableList<Animal>,这样就可以向列表中添加DogCat实例了。 以下是代码示例(以Kotlin为例):
open class Animal
class Dog : Animal()
class Cat : Animal()

fun addAnimals(animals: MutableList<Animal>) {
    animals.add(Dog())
    animals.add(Cat())
}

在Java中代码如下:

import java.util.ArrayList;
import java.util.List;

class Animal {}
class Dog extends Animal {}
class Cat extends Animal {}

class Main {
    static void addAnimals(List<Animal> animals) {
        animals.add(new Dog());
        animals.add(new Cat());
    }

    public static void main(String[] args) {
        List<Animal> animalList = new ArrayList<>();
        addAnimals(animalList);
    }
}

在Python中没有泛型的概念,但是可以通过类型提示模拟类似功能,代码如下:

from typing import List


class Animal:
    pass


class Dog(Animal):
    pass


class Cat(Animal):
    pass


def addAnimals(animals: List[Animal]):
    animals.append(Dog())
    animals.append(Cat())


animalList = []
addAnimals(animalList)

如果要保持泛型的灵活性,可以使用in关键字(逆变),但这里更简单直接的方式是使用MutableList<Animal>,因为它能满足添加DogCat实例的需求。