首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

为什么对基类的赋值有效,但是对派生类的赋值是编译错误?

这个问题涉及到面向对象编程中的继承和多态的概念。在Java中,基类和派生类之间的赋值问题可以通过以下方式来解释:

当我们将一个基类对象赋值给一个派生类对象时,实际上是将一个基类对象的引用指向一个派生类对象。由于派生类对象包含了基类对象的所有属性和方法,因此基类对象可以访问派生类对象的属性和方法。这就是为什么对基类的赋值有效的原因。

然而,当我们尝试将一个派生类对象赋值给一个基类对象时,情况就不同了。由于基类对象并不包含派生类对象的所有属性和方法,因此在赋值过程中会出现类型不匹配的问题。这就是为什么对派生类的赋值是编译错误的原因。

为了解决这个问题,我们可以使用向下转型来实现。向下转型是将一个派生类对象转换为基类对象的过程。在Java中,可以使用以下代码来实现向下转型:

代码语言:txt
复制
DerivedClass derived = new DerivedClass();
BaseClass base = (BaseClass) derived;

通过向下转型,我们可以将派生类对象赋值给基类对象,从而避免编译错误。但是需要注意的是,在进行向下转型时,必须确保派生类对象是基类对象的实例,否则会出现运行时错误。

总之,对基类的赋值有效是因为基类对象可以访问派生类对象的属性和方法,而对派生类的赋值是编译错误是因为基类对象不能访问派生类对象的所有属性和方法。通过向下转型,我们可以将派生类对象赋值给基类对象,从而避免编译错误。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

C++中派生类成员访问形式

C++中派生类成员访问形式主要有以下两种: 1、内部访问:由派生类中新增成员继承来成员访问。 2、对象访问:在派生类外部,通过派生类对象继承来成员访问。...今天给大家介绍在3中继承方式下,派生类成员访问规则。...private成员在私有派生类不可直接访问,所以无论派生类成员还是通过派生类对象,都无法直接访问从继承来private成员,但是可以通过提供public成员函数间接访问。...private成员在私有派生类不可直接访问,所以无论派生类成员还是派生类对象,都无法直接访问从继承来private成员,但是可以通过提供public成员函数直接访问它们。...private成员在私有派生类不可直接访问,所以无论派生类成员还是通过派生类对象,都无法直接访问private成员。

2.4K70

派生类中虚函数和非虚函数继承效果

base3 a1->leg(); //base1 a1->head(); //base2 Bird * a1 = new Bird(); return 0; } 为什么输出为...base3,因为eye个普通函数,在编译阶段就确定好被谁调用,所以他只认哪个指针指向自己,这里Animal指针指向,所以他就调用Animal里面的,普通函数为子类提供“强制实现”,也就是只要是父指针调用普通函数...,那就是父普通函数 而虚函数作用,主要是为了让父指针可以调用子类函数,这种在运行时才决定调用哪个函数 1、虚函数:   C++虚函数主要作用是“运行时多态”,父中提供虚函数实现,为子类提供默认函数实现...子类可以重写父虚函数实现子类特殊化。 2、纯虚函数:   C++中包含纯虚函数,被称为“抽象”。抽象不能使用new出对象,只有实现了这个纯虚函数子类才能new出对象。   ...3、普通函数:   普通函数静态编译,没有运行时多态,只会根据指针或引用“字面值”对象,调用自己普通函数。   普通函数为子类提供“强制实现”。

8410
  • 都知道这么做但是能说为什么没多少 ...

    在坐标内画 n 条垂直线,垂直线 i 两个端点分别为 (i, ai) 和 (i, 0) 。 找出其中两条线,使得它们与 x 轴共同构成容器可以容纳最多水。 ? 说明:你不能倾斜容器。...由于构成矩形面积,取决于 i 和 j 之间距离(记为 w) 和 i 和 j 下标对应高度最小值(记为 h)。...首先无论 i 指针往右移动还是 j 指针往左移动都会导致 w 变小,所以想要能够枚举到更大面积,我们应该让 h 在指针移动后变大。...不妨假设当前情况 height[i] < heigth[j](此时矩形高度为 height[i]),然后分情况讨论: 让 i 和 j 两者高度小指针移动,即 i 往右移动: 移动后,i 指针对应高度变小...复杂度为 空间复杂度: 最后 这是我们「刷穿 LeetCode」系列文章第 No.11 篇,系列开始于 2021/01/01,截止于起始日 LeetCode 上共有 1916 道题目,部分有锁题

    3.3K20

    《C++Primer》第十五章 面向对象程序设计

    正确:动态类型Bulk_quote Bulk_quote *bulkP = itemP; // 错误:不能将转换成派生类 编译器在编译时无法确定某个特定转换在运行时是否安全,这是因为编译器只能通过检查指针或引用静态类型来推断该转换是否合法...3. final和override说明符 派生类如果定义了一个函数与中虚函数名字相同但是形参列表不同,这仍然合法行为。编译器认为新定义这个函数与中原有的函数相互独立。...C++11新标准中我们可以使用override关键字来说明派生类虚函数,这样做好处使得程序员意图更加清晰同时让编译器为我们发现错误。...虚函数与作用域 从名字查找先于类型检查我们可以得知为什么派生类虚函数为什么必须有相同形参列表了。...合成拷贝控制与继承 派生类合成拷贝控制成员与其他合成构造函数、赋值运算符或析构函数类似:它们本身成员依次进行初始化、赋值或销毁操作。

    1.2K20

    C++:43---派生类转换、静态动态变量

    二、转换本质 派生类可以转换为本质: ①为什么派生类可以转换为派生类而来,因此派生类中包含了方法和成员。...此时可以通过指针或引用指向派生类(相当于将派生类中继承那部分方法和成员绑定到上了,相当于派生类被截断了),然后就可以将派生类假装一个对象来使用(调用其中成员/方法) ②为什么不能转换为派生类...:因为派生类可能会定义自己新成员/方法,但是这些成员/方法中所没有的。...,错误 五、静态类型/动态类型 在上面我们介绍过,指针或引用可以指向于对象也可以指向于派生类对象,因此一个可以分为动态类型还是静态类型: 静态类型变量:在编译时就已经知道是什么类型了...//错误,num属于B,而A内不含有此成员 return 0; } 七、其他情境下类型转换 当我们用一个派生类对象为一个对象初始化或赋值时,只有该派生类对象中部分会被拷贝、移动或赋值

    1.7K10

    《Effective C++》读书笔记(二):构造析构赋值运算(条款05~条款12)

    析构时候,先是派生类先析构,然后析构。 书中补充①:需要注意编译器产生析构函数并非虚函数。...还有一种情况在继承情况下,将自己赋值重载函数设为私有的,那么编译器就会拒绝给派生类默认生成赋值重载函数。...理由是,派生类继承时候,会继承某些成分,编译器要处理这些成分,但是因为无法调用派生类无权调用成员函数,因此也就没办法了。...理由是派生类实例化出来对象后,有一部分成分,因此需要调用对应成员函数,如果进行了赋值或者拷贝操作,就需要调用对应函数,而这些函数被删掉了或者私有化,反正调用不了,此时派生类拷贝构造和赋值重载也不能用了...这样做好处,如果有人在中调用了这些被私有化函数,或者使用友元,那么会在连接期出现错误,而并非编译错误。如果发生在连接期错误,这种错误很难侦测出来!

    36310

    c++和继承面试点25连问

    还有一种就是继承了某样东西,但是派生类需要重新实现一下,也就是接口继承,下面第三点要讲多态就是接口继承典型代表; 多态,多种形态,就是我们使用指针或者引用调用某个函数时,编译期并不知道到底要调用哪个函数...覆盖派生类函数覆盖函数,覆盖特征: 不同范围,即函数分别位于派生类中; 函数名字相同; 函数参数相同; 函数必须有virtual关键字。...隐藏派生类函数屏蔽了与其同名函数,特征如下: 如果派生类函数与函数同名,但是参数不同,此时不论有没有virtual关键字,函数都将被隐藏; 如果派生类函数与函数同名,参数也相同...因为销毁时候直接销毁指针,此时编译器只知道调用析构,并不会主动去调用派生类析构函数,所以析构函数需为虚析构函数,这样运行时程序才会去调用派生类析构函数,其实这就相当于析构函数多态,...如果使用了空指针,就会发生段错误,那这里肯定也会发生段错误,但实际上编译执行后并没有产生错误,print函数被正确执行了,这就很尴尬了,这是为什么呢?

    98310

    【C++】继承

    有一个例子可以证明赋值过程天然,比如下面代码中临时变量常引用问题,如果有临时变量产生,则子类对象给对象赋值引用时,必须用常引用,但是可以看到,不需要用常引用,那就说明不会有临时变量产生,赋值过程天然...,因为中间产生临时变量具有常性,需要用const引用 //派生类对象赋值转换也叫做向上转换,但是不能向下转换,因为父缺少子类中特殊那一部分,无法进行赋值转换。...答案错误,因为构成重载函数前提必须在同一作用域,派生类两个不同域,所以并不构成重载,而是构成隐藏。...所以说,派生类中其他三个默认成员函数都必须我们自己手动调用对应默认成员函数,但是析构函数不需要我们自己调用,编译器在子类析构调用结束后会自动调用析构。 5....继承在一定程度上破坏了封装,改变,派生类有很大影响。派生类依赖关系很强,耦合度高。 4. 对象组合继承之外另一种代码复用选择。

    69910

    C++:52---多重继承

    使用非合成版本 与单一继承原理一致,多重继承派生类如果定义了自己拷贝/赋值构造函数和赋值运算符,则必须在完整对象上执行拷贝、移动、赋值操作(也就是说建议要拷贝、移动、赋值属于部分数据)...使用合成版本 如果派生类没有定义自己拷贝/赋值构造函数和赋值运算符,那么在执行这些操作时将会自动调用拷贝/赋值构造函数和赋值运算符 七、派生类类型转换 与单一继承原理一致,可以将一个派生类赋值给一个...编译器不会在派生类转换中进行比较和选择,因为在它看来转换到任意一种都一样。...但是如果我们通过派生类同名数据成员/函数进行调用,那么就会触发二义性 class A { public: int num; }; class B { public: int num; };...1中private,在2中protected,也会发生错误

    94730

    EasyC++82,继承和动态内存分配

    这里面有一个问题,当我们使用动态内存分配,并且重新定义赋值和复制构造函数,这会对派生类实现有什么影响呢? 我们来看两种情况。...答案不需要。 首先是析构函数,这个很好想明白,如果我们没有定义析构函数,那么编译器会自动定义一个不执行任何操作默认析构函数。...实际上派生类析构函数往往会在执行一些逻辑之后调用构造函数,因为lackDMA成员不是通过new创建,因此不需要额外操作,所以默认析构函数合适。...赋值也是一样,默认赋值运算符也会自动使用赋值运算符来成员进行赋值派生类使用new 我们再来看看派生类当中使用了new情况。...,我们直接用等于号赋值也有同样效果: *this = hs; 为什么不这么干呢?

    36720

    学过 C++ 你,不得不知这 10 条细节!

    最后还有一个情况:如果某个将 operator= 函数声明为 private ,编译器将拒绝为其派生类生成 operator= 函数。...,禁用了 复制构造函数 stu2 = stu1; // 错误,禁用了 赋值操作符函数 更容易扩展解决方式,可以专门写一个为阻止 copying 动作: class Uncopyale...多态性质需声明 virtual 析构函数 如果在多态性质,没有声明一个 virtual 析构函数,那么在 delete 指针对象时候,只会调用析构函数,而不会调用派生类析构函数,...问题出在 pa 指针指向派生类对象,而那个对象却经由一个指针被删除,而目前没有 virtual 析构函数。...说明,构造期间 virtual 函数绝不会下降到派生类阶层。取而代之,对象作为就像隶属于类型一样。

    75120

    【C++】从零开始认识继承

    寓意把派生类中父那部分切来赋值过去。 对象不能赋值派生类对象。 指针或者引用可以通过强制类型转换赋值派生类指针或者引用。但是必须指针指向派生类对象时才是安全。...3.4 派生类默认成员函数 6个默认成员函数,默认意思就是指我们不写,编译器会变我们自动生成一个,那么在派生类中,这几个成员函数如何生成呢?...但是我们写了一个Person全缺省构造函数,这里就会在没有传参时候没有默认构造函数匹配,这时派生类Student就会报错: 为了避免这样错误,我们可以增添派生类Student构造函数..._str) {} protected: int _num; //学号 string _str; }; Person(s) 会进行切片(子类对象可以赋值给父 ) ,这样代码复用!...术语 “白箱”相对可视性而言:在继承方式中,内部细节对子类可见 。继承一定程度破坏了封装,改变,派生类有很大影响。派生类依赖关系很强,耦合度高。

    7510

    C++之继承

    ---- 一、继承概念和定义 1.概念 继承机制面向对象程序设计使代码可以复用有效手段。...(这里不可见private成员还是被派生类继承,但是由于语法限制导致派生类对象无论内还是外都无法进行访问) protected保护成员限定符是因为继承才出现。...派生类对象可以赋值对象/指针/引用(形象来说就是将派生类切片,把派生类那部分切片赋值过去)。...当派生类中定义与父类同名成员时,派生类将屏蔽该成员直接访问,称这种情况为隐藏。而派生类同名成员成员重写/重定义。...编译器会对析构函数函数名进行特殊处理,即派生类析构函数名都会被处理为destructor()。因此派生类析构函数回构成隐藏。

    41410

    【C++】继承

    这里不可见私有成员还是被继承到了派生类对象中,但是语法上限制派生类对象不管在里面还是外面都不能去访问它,而不是派生类没有继承该成员。...如图所示:派生类对象赋值对象时直接将派生类中属于那一部分切割给,引用和指针也是一样,引用是派生类中属于那一部分成员别名,指针指向派生类中属于那一部分。..._count << endl; //5 return 0; } 1、编译错误:name Person 普通成员变量,存在于对象里面,当我们访问 name 时,编译器会到 ptr 指向...那么为什么进行虚继承对象中要记录距离虚偏移量呢?...所以继承一定程度破坏了封装,改变,派生类有很大影响,派生类依赖关系很强,耦合度高。 而对象组合继承之外另一种复用选择,新更复杂功能可以通过组装或组合对象来获得。

    89400

    【c++】继承学习(一):继承机制与派生类转换

    这里不可见私有成员还是被继承到了派生类对象中,但是语法上限制派生类对象不管在里面还是外面都不能去访问它 我们前面知道,里面可以访问它成员,但是private继承下,子类无法访问父成员...继承,因为protetced/private继承下来成员都只能在派生类里面使用,实际中扩展维护性不强 2.派生类对象赋值转换 派生类对象可以赋值对象 / 指针 / 引用...使用引用和指针时不会发生切片 对象切片问题仅在派生类对象被赋值给另一个类型对象时才会发生,比如当派生类对象被传值给一个对象函数参数,或者通过赋值构造一个新对象。...在使用引用或指针时,这种情况并不会发生 对象不能赋值派生类对象 指针或者引用可以通过强制类型转换赋值派生类指针或者引用。但是必须指针指向派生类对象时才是安全。...(int i) // 接受一个整型参数 { fun(); // 编译器将会提示错误:找不到不带参数 "fun" 函数。

    34210

    C++关键知识点梳理

    基本类型基本类型大小随编译器决定,下面以32位为例类型大小 (字节)bool未定义char1short2int4long4long long8float4double8变量变量初始化,在C++中,使用未初始化变量一种错误编程行为...引用只能绑定在对象上,而不能与字面量或者某个表达式计算结果绑定在一起;const 指针 & 引用函数指针:指向另一对象,对象不是别名,所以不需要定义时初始化,但是未经初始化指针容易引发运行时错误...宏类似于函数,但是其()中参数不是真的函数参数,在编译器进行宏展开时()里参数进行"一一"替换。...private继承方式所有 public 成员在派生类中均为 private 属性;所有 protected 成员在派生类中均为 private 属性;所有 private 成员在派生类中不能使用...当一个指针指向一个派生类对象时,虚函数表指针指向派生类对象虚函数表。当调用虚函数时,由于派生类对象重写了派生类对应虚函数表项,在调用时会调用派生类虚函数,从而产生多态。

    96930

    【笔记】《C++Primer》—— 第三部分:设计者工具

    =&inp)来检测是否发生自赋值,若发生则不要进行内部控制权转移部分 移动后源对象必须保证有效且可安全析构状态,而且不能假设这个源对象任何值 一个可以既有移动拷贝也有拷贝构造,此时编译器将会进行最佳匹配...每次继承一个就会在内存中生成一个子对象,存放了成员,也正是因为这个原因派生类可以转换为 派生类构造函数需要负责所有成员初始化,尽管派生类也可以初始化继承来成员,但是这不符合通常编码思路...定义方法在声明函数名时候函数体类似显式默认构造写法改写为=0,只能对虚函数使用这个写法 友元只对被声明有效,友元派生类都不是友元 某个其继承来成员访问权限受到两个因素影响:...中此成员访问说明符,这是最重要一部分 派生类派生列表访问说明符,这一项决定派生类继承来成员对外表现出最高权限 有时候我们需要改变外部派生类继承某个名字访问级别,可以在自己访问控制符处用...因此除了重载虚函数外最好不要让名称同名 派生类可以覆盖重载函数,但是如果派生类希望重载几个函数都在派生类中可见的话:一种方法不覆盖任何一个重载函数或将所有重载函数都进行一次覆盖;另一种方法为需要重载函数名使用

    1.7K10

    C++进阶:继承

    注意:这里这是不能访问,但是还是继承了 可以看到这里继承了,但是不能访问 如果访问方式还是不清楚,可以看看上面的表格,再看看上面的规则。...这里不可见私 有成员还是被继承到了派生类对象中,但是语法上限制派生类对象不管在里面还是外面 都不能去访问它。...我们可以这样理解: 赋值兼容转换可以理解为,我们将一个派生类拷贝给一个实际上派生类部分拿出来单独给,这里就像切片一样,把派生类切开,把部分给,所以这里才取名为切片或者切割...void Test() B b; b.fun(); }; 上面这个调用哪个fun呢?这里就不卖关子了,这里会报错。 这里直接会报编译错误,如果我们想调用A函数怎么办呢?...但是我们可以看见,一个对象调用了两次析构,而且还是先析构成员,所以这里我们就不需要显示写出来,直接等编译器自动调用即可。

    10310

    《逆袭进大厂》第三弹之C++提高篇79问79答

    如果派生类中给出了纯虚函数实现,则该派生类就不再抽象了,它是一个可以建立对象具体。 抽象不能定义对象。一个纯虚函数不需要(但是可以)被定义。...,但是对于该类派生类来说,相当于公有成员,在派生类中可以被访问。...2) 三种继承方式 ① 若继承方式public,成员在派生类访问权限保持不变,也就是说,成员访问权限,在派生类中仍然保持原来访问权限; ② 若继承方式private,所有成员在派生类访问权限都会变为私有...指针,加上指针大小; 4) 当该该类某类派生类,那么派生类继承部分数据成员也会存在在派生类空间中,也会对派生类进行扩展。...左值和右值 左值:表示可以获取地址表达式,它能出现在赋值语句左边,该表达式进行赋值

    2.2K30
    领券