首页
学习
活动
专区
工具
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、普通函数:   普通函数是静态编译的,没有运行时多态,只会根据指针或引用的“字面值”类对象,调用自己的普通函数。   普通函数是父类为子类提供的“强制实现”。

9210
  • 都知道这么做是对的,但是能说为什么的没多少 ...

    在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0) 。 找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。 ? 说明:你不能倾斜容器。...由于构成矩形的面积,取决于 i 和 j 之间的距离(记为 w) 和 i 和 j 下标对应的高度的最小值(记为 h)。...首先无论是 i 指针往右移动还是 j 指针往左移动都会导致 w 变小,所以想要能够枚举到更大的面积,我们应该让 h 在指针移动后变大。...不妨假设当前情况是 height[i] 的高度为 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.8K10

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

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

    37110

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

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

    99410

    【C++】详细讲解继承(上)

    这⾥的不可⻅是指基类的私有成员还是被继承到了派⽣类对象中,但是语法上限制派⽣类对象不管在类⾥⾯还是类外⾯都不能去访问它。...,需要指定⼀下类域, 否则编译报错:error C3861: “push_back”: 找不到标识符 相关的错误。)...但是必须是基类的指针 是指向派⽣类对象时才是安全的。(等以后细说) 3.继承中的作用域 3.1 隐藏规则 下面的类基类和派生类有一个同名的成员变量是_name。...派⽣类和基类中有同名成员,派⽣类成员将屏蔽基类对同名成员的直接访问,这种情况叫隐藏。..._num) { //假设里面是深拷贝资源的拷贝逻辑 } Same是父类,Same后面的括号里应该传父类的对象,但是我们没有父类的对象,只有子类的对象s,为什么可以直接传s过去?

    4000

    【C++】继承

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

    71010

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

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

    96230

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

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

    37020

    探索CC++的奥秘之C++中的继承

    基类private成员在派生类中无论以什么方式继承都是不可见的。这里的不可见是指基类的私 有成员还是被继承到了派生类对象中,但是语法上限制派生类对象不管在类里面还是类外面都不能去访问它。 2....2.基类和派生类对象赋值转换 Person p; Student s; p = s; s = p;//这种写法是不行的,即使强制类型转换也不行 s = (Person)p;//错误写法 1....派生类对象可以赋值给基类的对象 / 基类的指针 / 基类的引用。...引用:  指针:  2.基类对象不能赋值给派生类对象。 3.基类的指针或者引用可以通过强制类型转换赋值给派生类的指针或者引用。但是必须是基类的指针是指向派生类对象时才是安全的。...要是下面这样写: 正确的写法:  这里直接写Person(s)也可以, 因为基类的指针或者引用可以通过强制类型转换赋值给派生类的指针或者引用。 如果不写:Person(s): 为什么不是张三呢?

    12210

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

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

    75520

    C++之继承

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

    42010

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

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

    8110

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

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

    37910

    C++关键知识点梳理

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

    98430

    【C++】———— 继承

    所以我们这里可以得到以下几个理论: 积累private成员在派生类中无论以什么方式继承都是不可见的,这里的不可见是指基类的私有成员还是被派生类对象中,但是语法上限制派生类对象不管在类里面还是在类外面都无法去访问他们...二、基类与派生类的赋值转换: 我们在前面的学习知道相近类型之间是能够赋值,因为他们之间会发生隐式类型转换。...但是必须是基类的指针是指向派生类对象时才是安全的。这里基类如果是多态类型,可以使用RTTI,dynamic_cast 来进行识别后进行安全转换。...四、派生类的默认成员函数 我们知道在类中有6个默认成员函数,如果不显示定义,编译会自动生成。那么如果在派生类中,这几个成员函数是如何生成的呢?...继承一定程度破坏了基类的封装,基类的改变,对派生类有很大的影响。派生类和基类间的依赖关系很强,耦合度高。 8.2. has-a关系 组合是一种has - a的关系。

    8310

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

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

    1.7K10
    领券