RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 934104
Accepted
ghostinecatnewyear
ghostinecatnewyear
Asked:2020-01-20 00:26:27 +0000 UTC2020-01-20 00:26:27 +0000 UTC 2020-01-20 00:26:27 +0000 UTC

哎呀。父类类型的类对象

  • 772

在 OOP 主题的示例中,我经常注意到基于某个类创建的对象存储在“父类”类型的变量中。让我用一个例子来解释:

class Pet {
    // реализация
}


class Cat extends Pet {
    // реализация
}

然后,在 main 方法中:

Pet myCat = new Cat();

“根据经典”,myCat 变量应该被声明为 Cat 类型,这是合乎逻辑的。我注意到通过这种方式可以将不同类型的对象分组到集合中,但是具有相同的祖先,但是,这些对象的所有功能都将仅限于这个祖先。

我想知道为什么要这样做,以及你能从中得到什么或失去什么。

java
  • 3 3 个回答
  • 10 Views

3 个回答

  • Voted
  1. Best Answer
    Vladimir Yarovoy
    2020-01-20T05:27:17Z2020-01-20T05:27:17Z

    你可以举一个基于Java的例子。您在某些方法中声明了一个集合对象,但您使用 List 接口定义它

    List<> myList = new ArrayList<>();
    

    您的对象将使用 List 接口具有的方法,而您可以将对象强制转换为 ArrayList 实现并使用 ArrayList 方法

    (ArrayList)myList.get(0);
    

    但是如果你不这样做,而是严格使用 List 接口中描述的方法,你可以随时更改 ArrayList 的实现,例如改为 LinkedList,为此你只需修复代码中的一行,在变量的定义中,其余代码不必更改。

    List<> myList = new LinkedList<>();
    

    因此,例如,ArrayList 允许您非常快速地访问元素 - 复杂度 O (1),而用于访问元素的 LinkedList 具有复杂度 O (n)。同时,ArrayList 需要更长的时间将元素插入到集合的中间,而对于 LinkedList 来说这是一个非常快的操作。当您开始编写代码时,您可以使用一些泛型类来描述您的变量,然后您可以快速转向该类的更有益的实现。

    • 3
  2. AnT stands with Russia
    2020-01-24T17:18:25Z2020-01-24T17:18:25Z

    您提供的示例

    Pet myCat = new Cat();
    

    以这种形式,它仅在“引用”编程语言中才有意义,其中myCat它实际上不是类型变量Pet(正如您错误地假设的那样),而是可以引用类的子层次结构中任何类型的对象的引用根Pet。这样的链接将表现出多态性,即 尽管它在外部具有 type Pet,但它的行为就像Cat(在公共接口的框架内)。

    实际上,您提供的示例旨在演示的正是这种多态性。

    在 C++ 中,必须显式声明类型“引用”,您的原始示例没有意义。在 C++ 中,您必须执行相同的操作,例如通过指针

    Pet *myCat = new Cat();
    

    这里可以清楚的看到Pet左边其实没有类型变量。只有一个指向 的指针(或某种其他形式的引用)Pet实际上指向Cat。

    • 1
  3. Андрей Туманов
    2020-01-24T17:11:59Z2020-01-24T17:11:59Z

    该问题说明了 OOP 中“多态性”原则的典型实现。

    要理解这个原理,有必要了解几个重要的点:

    1. 在经典的 OOP 中,对象是基于某种类型(类)创建的,并且在该对象的生命周期中,创建它所基于的类型不能更改。例外情况是某些编程语言可以修改已创建的对象 - 可以向该对象添加新方法和其他扩展,但这在所讨论问题的上下文中并不重要。对象的类型在其生命周期内不会改变这一事实的后果之一是,将完全使用创建该对象的类的方法和属性的整个实现。不管这个对象的这个或那个方法是如何被调用的。因此,如果我们在给定对象上调用方法,我们总是会得到给定对象所基于的类型的行为。来自 TS 问题 - 变量方法myCatCat即使变量的类型是.也会执行类的行为Pet。

    2. 变量类型决定了可用于该变量的方法集。例外的是一些对象类型允许你通过名字来调用对象的方法,例如object很多编程语言中的一个类型可以用来调用对象的任何方法而无需键入它。通过这样的调用,将执行后期绑定,如果这样的对象有被调用的方法,那么它将被执行,如果它不存在,则会产生运行时错误!不是编译时错误!。

    3. 将对该基类的任何后代的对象的引用放入基类类型变量中是完全安全的。这在 TC question 的代码行中做得非常正确 Pet myCat = new Cat(); ,这不会改变对象类型,但基类变量本身的类型将限制由于该变量而可以调用的方法集。例如,如果在类Cat中定义了公共方法CatMyau,则从变量调用此方法myCat将不起作用,因为该方法在类中不存在Pet。

    4. 在创建了基类对象的集合后,我们可以处理该类的任何子对象。例如,我们可以创建一个包含宠物的集合,Pet我们可以为一个类定义一个抽象的公共方法Voice,并为基类的所有后代实现该方法。例如,Cat它会喵喵叫,狗会吠叫。当遍历宠物时,我们可以调用变量 type 上的Pet方法Voice,并且根据放置在我们集合中的类对象,我们将听到一只或另一只动物的声音。猫会喵喵叫,狗会叫。

    • 0

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    根据浏览器窗口的大小调整背景图案的大小

    • 2 个回答
  • Marko Smith

    理解for循环的执行逻辑

    • 1 个回答
  • Marko Smith

    复制动态数组时出错(C++)

    • 1 个回答
  • Marko Smith

    Or and If,elif,else 构造[重复]

    • 1 个回答
  • Marko Smith

    如何构建支持 x64 的 APK

    • 1 个回答
  • Marko Smith

    如何使按钮的输入宽度?

    • 2 个回答
  • Marko Smith

    如何显示对象变量的名称?

    • 3 个回答
  • Marko Smith

    如何循环一个函数?

    • 1 个回答
  • Marko Smith

    LOWORD 宏有什么作用?

    • 2 个回答
  • Marko Smith

    从字符串的开头删除直到并包括一个字符

    • 2 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5