协变和逆变泛型类型_第1页
协变和逆变泛型类型_第2页
协变和逆变泛型类型_第3页
协变和逆变泛型类型_第4页
协变和逆变泛型类型_第5页
已阅读5页,还剩22页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1/1协变和逆变泛型类型第一部分协变泛型类型定义 2第二部分协变泛型类型的类型约束 5第三部分协变泛型类型的上界 8第四部分协变泛型类型的应用场景 11第五部分逆变泛型类型定义 14第六部分逆变泛型类型的类型约束 17第七部分逆变泛型类型的下界 21第八部分逆变泛型类型的应用场景 24

第一部分协变泛型类型定义关键词关键要点协变泛型类型定义

主题名称:协变泛型类

*

*协变泛型类是一种允许其泛型参数类型在子类中进行扩展的泛型类。

*子类可以扩展超类的泛型参数类型,但不能缩小,即子类使用的类型必须是超类类型或其子类型。

*协变泛型类主要用于表示继承关系中的多态性,允许子类提供超类泛型参数的更具体或派生类型。

主题名称:协变泛型接口

*协变泛型类型定义

在泛型编程中,协变泛型类型是指:

*对于类型参数`T`,如果`S`是`T`的子类型,则`Collection<S>`也是`Collection<T>`的子类型。

换句话说,如果一个泛型类型接收一个子类型作为其类型参数,则它可以被视为接受父类型作为其类型参数。

正式定义

协变泛型类型的正式定义如下:

对于泛型类型`C<T>`和类型`S`和`T`,其中`S`是`T`的子类型:

*如果`x`是类型`C<S>`的值,则`x`也是类型`C<T>`的值。

*如果`T`和`S`是引用类型,则`C<S>`和`C<T>`是可赋值兼容的。

换句话说,一个协变泛型类型`C<T>`满足以下条件:

*`C<T>`和`C<S>`是可赋值兼容的,其中`S`是`T`的子类型。

*`C<S>`中的每个`T`实例都可以在不进行显式转换的情况下分配给`C<T>`中的`T`实例。

示例

让我们举一个协变泛型类型的示例:

```java

privateTvalue;

returnvalue;

}

this.value=value;

}

}

```

`Box`是一个协变泛型类型,因为如果`S`是`T`的子类型,则`Box<S>`也是`Box<T>`的子类型。

这意味着我们可以执行以下操作:

```java

Box<Animal>animalBox=newBox<>();

animalBox.setValue(newDog());//Dog是Animal的子类型

Box<Mammal>mammalBox=animalBox;//协变性允许此赋值

```

`mammalBox`现在包含一个`Dog`对象,即使它声明为`Box<Mammal>`。这是因为协变性允许我们将`Box<Animal>`赋值给`Box<Mammal>`,因为`Animal`是`Mammal`的子类型。

协变性规则

以下是一些关于协变泛型类型的规则:

*如果一个类型参数出现在协变位置(如返回类型或输出参数),则该类型参数是协变的。

*如果一个类型参数出现在逆变位置(如参数类型或输入参数),则该类型参数是逆变的。

*一个类型参数不能同时是协变的和逆变的。

*一个泛型类型可以具有多个类型参数,其中一些是协变的,而另一些是逆变的。

协变性的好处

协变泛型类型提供以下好处:

*类型安全:协变泛型类型确保类型安全,因为它们只允许在类型系统允许的情况下进行赋值。

*代码可读性:协变泛型类型使代码更具可读性和可维护性,因为它允许我们将相关类型与泛型类型联系起来。

*代码重用:协变泛型类型促进代码重用,因为它允许我们创建可用于多种子类型的通用算法和数据结构。

注意事项

需要注意的是,协变泛型类型并不总是适用于所有情况。如果协变泛型类型被用于违反类型安全的情况下,则可能会导致运行时错误。

例如,让我们修改`Box`类以支持泛型数组:

```java

privateT[]values;

returnvalues;

}

this.values=values;

}

}

```

现在,`Box`仍然是一个协变泛型类型,但它不再是类型安全的。原因是我们可以将`Box<Animal>`赋值给`Box<Mammal>`,然后向`Box<Mammal>`中添加一个`Bird`对象。这将导致运行时错误,因为`Bird`不是`Mammal`的子类型。

为了避免此类错误,应谨慎使用协变泛型类型,并确保它们不会违反类型安全。第二部分协变泛型类型的类型约束关键词关键要点协变泛型类型的类型约束

协变泛型类型约束是泛型类型系统中的一种重要机制,它允许派生类使用与基类具有相同或更宽泛类型的泛型参数。这提供了更大的灵活性,并且可以防止因类型检查错误而出现意外行为。

主题名称:协变泛型类型约束的优点

1.提高代码的可重用性:协变泛型类型约束允许派生类重用基类的泛型方法和属性,而无需重新编写代码。

2.增强类型安全性:通过确保派生类的泛型参数与基类的泛型参数具有相同或更宽泛的类型,协变泛型类型约束有助于防止类型不匹配错误。

3.提高代码的可读性和可维护性:通过明确指定泛型参数的协变关系,协变泛型类型约束可以使代码更容易理解和维护。

主题名称:协变泛型类型约束的限制

协变泛型类型的类型约束

协变泛型类型是对生产者泛型类型的一种约束,它规定了类型参数在子类和超类之间的协变关系。换句话说,它确保了类型参数在子类中至少与在超类中相同或更具体。

定义和符号

*协变泛型类型:定义为`<outT>`,其中`T`是类型参数。

*类型约束:`T`必须是一个引用类型或`null`。

*子类:如果`S`是`T`的子类,则`<outS>`是`<outT>`的子类。

*超类:如果`T`是`S`的超类,则`<outT>`是`<outS>`的超类。

规则

协变泛型类型的类型约束遵循以下规则:

*赋值兼容性:如果`<outT>`和`<outS>`是协变泛型类型,并且`S`是`T`的子类,则`<outS>`可以赋值给`<outT>`。

*类型擦除:与协变泛型类型关联的实际类型在编译时被擦除。

*协变方法:协变泛型类型的实例方法可以返回协变泛型类型的子类实例。

*协变字段:协变泛型类型的字段可以被更具体的协变泛型类型的子类字段所覆盖。

*数组协变:协变泛型类型的数组是协变的。这意味着`<outT>[]`的子类是`<outS>[]`,其中`S`是`T`的子类。

优点

使用协变泛型类型有几个优点:

*安全性:它确保了类型安全,因为只允许将更具体或相同的类型分配给协变泛型类型。

*灵活性:它允许在不违反类型安全性的情况下处理子类和超类。

*代码简洁性:它减少了冗余代码,提高了代码可读性和可维护性。

局限性

使用协变泛型类型也有一些局限性:

*不可变性:协变泛型类型不能存储非空值,因为这可能导致类型不安全。

*限制使用:它仅适用于引用类型,而不能用于值类型。

*潜在的类型不安全:如果协变泛型类型与未经检查的类型一起使用,则可能导致类型不安全。

示例

以下是一个协变泛型类型的示例:

```java

privateList<T>list;

list=newArrayList<>();

}

list.add(item);

}

returnlist.get(index);

}

}

```

在这个示例中,`MyList`是一个协变泛型类型,因为它的类型参数`T`被声明为`<out>`。这意味着子类可以实例化`MyList`并存储更具体的类型,而无需出现类型不安全。

结论

协变泛型类型的类型约束是一种强大且有用的机制,用于确保类型安全并提高代码灵活性。但是,了解其局限性并正确使用它非常重要,以避免潜在的类型不安全。第三部分协变泛型类型的上界关键词关键要点协变泛型类型的上界

1.协变泛型类型允许其类型参数在子类中扩展。

2.这样可以将子类实例分配给父类类型的变量。

3.确保子类中的类型安全,因为它们继承了父类的类型约定。

【扩展性思考】

协变泛型类型在集合框架中应用广泛,例如列表和映射。

它允许在不牺牲类型安全性情况下处理集合中元素类型的多态性。

【前沿趋势】

泛型编程范例的不断发展正在推动对协变泛型类型的进一步研究。

探索复合泛型类型和高阶类型系统,以提高灵活性和代码可重用性。

协变泛型类型的实例

协变泛型类型的上界

简介

泛型允许我们创建可用于不同类型数据的类、方法和接口。协变类型允许子类类型参数化类型作为其超类类型参数化的替代类型。协变泛型类型的一个重要特征是其上界,它定义了可以用作协变类型参数的类型范围。

泛型类型的上界

协变泛型类型的上界是一个父类,它指定了可用于实例化协变泛型类型的类型。此上界确保了协变类型的安全性,因为它只能接受子类或自身作为参数。

协变泛型类型的特点

*读取安全性:如果一个类是协变泛型类型的子类,那么它可以被赋值给该泛型类型的父类变量,即使它持有不同类型的元素。

*类型安全性:上界确保了协变泛型类型的类型安全,因为它限制了可用于实例化的类型。

*向上转换:协变类型可以向上转换为其上界类型,而不丢失任何信息。

协变泛型类型上界的限制

协变泛型类型的上界有一些限制:

*写入安全性:协变泛型类型不能写入,因为无法保证赋值时的类型安全性。

*不能存储基类类型:协变泛型类型不能存储其上界类型,因为这会导致类型安全问题。

*不能创建新的实例:协变泛型类型不能创建其上界类型的实例,因为这会导致类型不安全。

上界实例

以下是一些协变泛型类型上界的实例:

*`List<T>`:`T`可以在此协变泛型类型中存储任何类型的对象,但只能读取,不能写入。

*`Comparable<T>`:`T`可以是任何可比较的类型。

*`OutputStream<T>`:`T`可以是任何可写入的数据类型。

上界和协变

协变泛型类型与其上界之间存在着密切的关系:

*上界定义了协变泛型类型允许的类型。

*协变性允许协变泛型类型接受其上界的子类。

优点

协变泛型类型上界的使用具有以下优点:

*代码重用:允许使用通用代码,无论底层类型是什么。

*类型安全性:确保协变类型的安全,防止类型不匹配。

*向上转换:简化了向上转换为父类类型的过程。

缺点

协变泛型类型上界也有一些缺点:

*写入安全性:限制了协变类型的写入能力。

*存储基类类型:限制了存储基类类型的能力。

*创建新实例:限制了创建新实例的能力。

结论

协变泛型类型上界是协变泛型类型的一个重要方面,它定义了可用于实例化的类型范围。通过确保类型安全性、向上转换和代码重用,协变泛型类型上界为编写健壮且灵活的代码提供了许多好处。然而,了解其限制对于避免类型安全问题至关重要。第四部分协变泛型类型的应用场景关键词关键要点集合框架

*协变泛型类型允许在集合中存储子类型对象。

*例如,一个`List<Animal>`可以存储`Dog`和`Cat`对象。

*这使得集合框架更加灵活和易于使用,因为它消除了对显式强制转换的需要。

数据结构

*协变泛型类型可以用来表示层次数据结构。

*例如,一个`Tree<Shape>`可以存储`Circle`、`Rectangle`和`Triangle`对象。

*这упростило表示和操作复杂数据结构,因为它允许在不同层级中使用相同的接口。

接口设计

*协变泛型类型可以用来创建更通用的接口。

*例如,一个`Comparator<T>`接口可以用来比较`T`类型的对象。

*由于`Comparator`是协变的,它也可以用来比较`T`的子类型。

委托

*协变泛型类型可以用来简化委托。

*例如,一个方法可以接受一个`Action<Animal>`委托。

*该方法可以使用`Action`来执行其他操作,而无需显式强制转换。

类型推断

*编译器可以使用协变泛型类型来推断类型参数。

*例如,如果一个方法接受一个`List<Animal>`参数,编译器可以推断该参数的类型为`List<Dog>`或`List<Cat>`。

*这упростило编写代码,因为它消除了对显式类型注释的需要。

性能优化

*协变泛型类型可以帮助优化性能,因为它消除了强制转换所需的开销。

*例如,从`List<Animal>`访问`Dog`对象时,不需要强制转换。

*这可以显著提高性能,尤其是在处理大量数据时。协变泛型类型的应用场景

协变泛型类型在编程中具有广泛的应用,特别是在涉及继承和多态性的场景中:

1.容器和集合

*JavaCollectionsFramework(JCF):JCF使用协变泛型类型定义集合类,例如`List<T>`和`Map<K,V>`。这允许将派生类的对象存储在基类定义的集合中,促进代码重用和灵活性。

2.继承层次结构

*返回类型协变:在一个继承层次结构中,子类可以覆盖父类的返回类型为其自身或其派生类型。例如,父类`Animal`定义方法`makeSound()`返回`Animal`,子类`Dog`可以覆盖`makeSound()`并返回`Dog`。

*参数类型协变:在一个继承层次结构中,父类可以声明接受其自身或派生类型作为参数的方法。例如,父类`Animal`定义方法`feed()`接受`Animal`作为参数,子类`Dog`可以覆盖`feed()`并接受`Dog`作为参数。

3.多态方法

*多态集合:协变泛型类型允许创建多态集合,其中元素可以是基类或其派生类的任意组合。例如,`List<Animal>`集合可以包含`Animal`、`Dog`和`Cat`对象。

*多态比较:协变泛型类型还支持将基类对象与它们的派生类对象进行比较。例如,可以将`Animal`对象与`Dog`对象进行比较,前提是`Animal`实现`compareTo()`方法。

4.代理模式

*动态代理:协变泛型类型可用于实现动态代理,允许在运行时创建代理类。代理类可以继承或实现接口,并为原始类提供额外的行为或功能。

5.可扩展框架

*插件和扩展:协变泛型类型允许创建一个可扩展的框架,其中可以插入和扩展来自不同来源的组件。例如,在图形框架中,可以创建接受不同类型形状的`Renderer`接口,允许添加不同的形状渲染器。

6.代码重用和抽象

*通用算法:协变泛型类型使创建适用于各种类型数据的通用算法成为可能。例如,排序算法可以按任意类型的元素进行排序。

*参数化类型:协变泛型类型允许创建参数化类型,其中类型参数指定了类型变量的行为。例如,`List<T>`类型可以通过提供`T`类型参数来创建特定类型的列表。

总之,协变泛型类型提供了强大的机制,允许在高度可扩展、可重用的和多态的代码中操作继承层次结构。它们广泛用于容器和集合、多态方法、代理模式、可扩展框架以及代码重用和抽象。第五部分逆变泛型类型定义关键词关键要点【逆变泛型类型定义】:

1.逆变泛型类型允许子类型作为父类型对象的替换类型。

2.对于逆变类型,子类中的实际类型可以分配给父类中的声明类型。

3.这种灵活性特别适用于表示"Is-a"关系的接口,因为子类也是父类的类型。

【逆变类型示例】:

逆变泛型类型定义

逆变泛型类型是一种泛型类型,当其子类型替换为其超类型时,它保持有效。这种特性与协变泛型类型相反,后者要求子类型替换为超类型时仍然有效。

逆变泛化类型语法

Java中逆变泛型类型的语法如下:

```java

Tget();

voidset(Tvalue);

}

```

其中,`T`是逆变泛型类型参数。

逆变泛型类型特征

逆变泛型类型的特点包括:

*泛型参数可以是类类型或接口类型:泛型参数可以是任何类类型或接口类型,包括原始类型(例如,`int`、`double`)或泛型类型。

*子类型替换超类型时仍然有效:当逆变泛型类型中的子类型替换为其超类型时,该类型仍然有效。这意味着可以将`Invariant<SubClass>`对象赋值给`Invariant<SuperClass>`变量,反之亦然。

*不能作为逆变类型参数的类型:逆变泛型类型不能用作另一个泛型类型的逆变类型参数。

逆变泛型类型用例

逆变泛型类型在以下场景中很有用:

*消费者类型:逆变泛型类型可以表示消费者类型,即可以接受各种对象并对其执行操作的类型。例如,`Callable<T>`接口可以表示一个可以接受`T`类型对象并对其进行操作的类型,当`T`是一个子类型时,它仍然有效。

*生产者类型:逆变泛型类型还可以表示生产者类型,即可以生成各种对象并返回它们的类型。例如,`Supplier<T>`接口可以表示一个可以生成`T`类型对象的类型,当`T`是一个超类型时,它仍然有效。

*比较器类型:逆变泛型类型可以用于定义比较器类型,即可以比较各种对象并确定其相对顺序的类型。例如,`Comparator<T>`接口可以表示一个可以比较`T`类型对象的类型,当`T`是一个子类型时,它仍然有效。

示例

`Invariant`接口的以下实现说明了逆变泛型类型:

```java

privateTvalue;

@Override

returnvalue;

}

@Override

this.value=value;

}

}

```

在此实现中,`T`是一个逆变泛型类型参数。因此,可以将`InvariantImpl<SubClass>`的实例赋值给`Invariant<SuperClass>`变量,反之亦然。

重要注意事项

使用逆变泛型类型时需注意以下事项:

*由于逆变泛型类型允许子类型替换其超类型,因此在类型安全方面存在潜在风险。例如,将`Invariant<SubClass>`实例分配给`Invariant<SuperClass>`变量时,编译器不会报错,但如果尝试从`Invariant<SuperClass>`获取超类型实例,则可能会引发ClassCastException。

*由于逆变泛型类型不能用作逆变类型参数,因此无法在泛型类或方法的签名中使用它们。第六部分逆变泛型类型的类型约束关键词关键要点逆变泛型类型的类型约束

主题名称:逆变类型约束的理解

1.逆变泛型类型用于表示父类或接口类型,它允许子类类型的实例分配给父类类型的变量。

2.逆变类型约束使用out关键字声明,表示变量可以引用子类类型的实例,但只能存储父类类型的引用。

3.这种约束应用于方法参数时,允许方法接受父类类型或其子类类型的实例。

主题名称:泛型接口中的逆变约束

逆变泛型类型的类型约束

引言

在协变泛型类型中,子类型可以赋值给父类型。与之相反,在逆变泛型类型中,父类型可以赋值给子类型。理解逆变泛型类型的类型约束对于正确使用它们至关重要。

泛型的逆变性

泛型类型可以是协变或逆变的。泛型类型`T`为协变的,当且仅当对于所有类型`S<:T`,都有`List<S><:List<T>`。泛型类型`T`为逆变的,当且仅当对于所有类型`S<:T`,都有`List<T><:List<S>`。

逆变泛型类型的类型约束

逆变泛型类型的类型约束指定了父类型可以赋值的子类型的条件。这些约束通常用于确保类型安全。

1.上界

对于逆变泛型类型`T`,可以指定一个上界`U`,表示`T`的所有子类型都必须派生自`U`。这种约束通常用于确保类型安全。例如:

```

Tproduce();

}

```

在这个例子中,`T`是逆变的泛型类型,它必须派生自`Number`。这意味着`Producer`可以产生任何派生自`Number`的类型,例如`Integer`、`Double`或`BigInteger`。

2.下界

对于逆变泛型类型`T`,可以指定一个下界`L`,表示`T`的所有子类型都必须是`L`的父类型。这种约束通常用于确保子类型具有所需的行为。例如:

```

voidconsume(Tvalue);

}

```

在这个例子中,`T`是逆变的泛型类型,它必须是`Comparable<T>`的父类型。这意味着`Consumer`可以接受任何实现了`Comparable`接口的类型,例如`Integer`、`Double`或`String`。

3.类型参数

逆变泛型类型的类型约束可以引用类型参数。这允许创建灵活的约束,这些约束可以适应不同的类型参数值。例如:

```

privateTfirst;

privateUsecond;

this.first=first;

this.second=second;

}

returnfirst;

}

returnsecond;

}

returnnewPair<>(mapper.apply(first),second);

}

}

```

在这个例子中,`Pair`类的`mapFirst`方法使用逆变泛型类型`V`,它必须派生自`T`。这允许方法在保持`Pair`类型不变的情况下修改第一个元素的类型。

4.通配符

通配符`?`可以用于表示逆变泛型类型的任何子类型。例如:

```

List<?superInteger>list=newArrayList<>();

list.add(10);//编译错误:无法向逆变列表中添加子类型

```

这个例子中的`list`是一个可以包含任何`Integer`的父类型的列表。这意味着可以向列表中添加`Integer`类型的元素,但不能添加派生自`Integer`的元素,例如`Long`。

5.原始类型

如果逆变泛型类型在未指定类型参数的情况下使用,它将默认为其原始类型。例如:

```

List<?>list=newArrayList<>();

list.add(10);//编译成功

```

这个例子中的`list`是可以包含任何类型的列表。这是因为`?`在没有类型参数的情况下默认为原始类型`Object`。

结论

逆变泛型类型的类型约束对于确保类型安全和灵活性至关重要。通过理解和正确使用这些约束,可以创建健壮、可维护的代码。第七部分逆变泛型类型的下界关键词关键要点【逆变泛型类型的下界】

1.逆变泛型类型可以用于表示“生产”关系,其中子类型可以安全地用于超类型的位置。

2.这是通过使类型参数具有上限边界来实现的,这意味着该参数只能是该上限类型的子类型。

3.这对于在方法中使用协变类型作为输入参数非常有用,在此情况下,可以安全地将超类型对象传递给子类型参数。

【逆变泛型类型在继承中的应用】

逆变泛型类型的下界

逆变泛型类型允许子类型赋值给父类型,这意味着子类类型可以安全地替换掉超类类型。

为了确保逆变性的安全性,逆变泛型类型必须具有下界,即指定该泛型类型的最小要求。下界确保子类型至少实现了父类型要求的最小功能。

逆变泛型类型只能具有接口类型的下界,不能具有类类型的下界。接口定义了一系列的方法和属性,而类则定义了具体的行为和实现。使用接口作为下界可以确保子类型具有父类型所需的功能,而不依赖于具体的类实现。

下界接口定义了泛型类型必须实现的最低要求。例如,考虑以下逆变泛型类型`Consumer`:

```

voidaccept(Tt);

}

```

该泛型类型定义了一个`accept`方法,用于处理类型`T`的实例。为了确保逆变性,`Consumer`类型必须具有下界接口,该接口定义`accept`方法的最低要求:

```

voidaccept(Objecto);

}

```

`Acceptor`接口定义了`accept`方法,该方法接受`Object`类型参数。这确保了任何实现了`Acceptor`接口的类都可以安全地替换`Consumer`类型。

逆变泛型类型的协变性

在某些情况下,逆变泛型类型也可以表现出协变性。协变性允许父类类型赋值给子类类型,这意味着父类型可以安全地接收子类型。

当逆变泛型类型具有协变上界时,才会发生协变性。上界指定该泛型类型的最大限制,协变上界允许父类型限制在比子类型更宽泛的范围内。

例如,考虑以下逆变泛型类型`Producer`:

```

Tproduce();

}

```

该泛型类型定义了一个`produce`方法,用于生成类型`T`的实例。为了确保逆变性,`Producer`类型必须具有下界接口,该接口定义`produce`方法的最低要求:

```

Objectproduce();

}

```

`Generator`接口定义了`produce`方法,该方法生成`Object`类型的值。这确保了任何实现了`Generator`接口的类都可以安全地替换`Producer`类型。

但是,由于协变上界`T`,`Producer`类型还可以表现出协变性。如果子类类型`T1`是父类类型`T`的子类型,那么`Producer<T1>`类型可以安全地赋值给`Producer<T>`类型,因为`T1`可以在`T`处使用。

逆变泛型类型的最佳实践

使用逆变泛型类型时,遵循以下最佳实践非常重要:

*清楚地定义下界接口:下界接口应明确定义泛型类型所需的最低要求。

*使用协变上界时要谨慎:协变上界可以引入类型安全问题,因此在使用时应格外小心。

*在代码注释中记录逆变性:明确记录泛型类型的逆变性,以帮助其他开发人员理解代码。

*尽量减少逆变泛型类型的嵌套:嵌套的逆变泛型类型可能会导致类型的复

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论