试图理解Java中的upcasting.最近发现奇怪的行为.
例:
public class A extends B {
public int i = 2;
public void printI() {
System.out.println("print i = " + this.i);
}
public static void main(String[] args) {
B a = new A(); // <- upcasting here
System.out.println("i = " + a.i);
a.printI();
}
}
class B {
public int i = 1;
public void printI() {}
}
//Output:
//i = 1
//print i = 2
Run Code Online (Sandbox Code Playgroud)
似乎,upcasted对象有两个独立的"i"属性.一个"i"可以直接访问(ai),另一个通过子类(a.printI())的方法访问.
看起来像upcasted对象从超类和子类的方法获取属性.
对象如何拥有两个独立的"我"?!
假设以下课程
class Base
{
void Doajob(a,b){...}
}
class Derived: public Base
{
void Doanotherjob(a,b,c){...}
}
Run Code Online (Sandbox Code Playgroud)
我已经定义了一个指针如下:
auto ptr= unique_ptr<Base>(new Derived(name));
Run Code Online (Sandbox Code Playgroud)
现在我想使用ptr指针访问Doanotherjob:
ptr->Doanotherjob(a,b,c); // ERROR
((unique_ptr<Base>) ptr)->Doanotherjob(a,b,c); // ERROR
((unique_ptr<Derived>) ptr)->Doanotherjob(a,b,c); // ERROR
Run Code Online (Sandbox Code Playgroud)
那是不是一件正确的事情?语法是什么?
在我的例子中:
在向上看,第二次d.print()
打电话不应打印"基地"吗?
是不是"d"派生对象上传到基类对象?
在低迷时期,它有什么优势?
你能用实际的方式解释上传和下传吗?
#include <iostream>
using namespace std;
class Base {
public:
void print() { cout << "base" << endl; }
};
class Derived :public Base{
public:
void print() { cout << "derived" << endl; }
};
void main()
{
// Upcasting
Base *pBase;
Derived d;
d.print();
pBase = &d;
d.print();
// Downcasting
Derived *pDerived;
Base *b;
pDerived = (Derived*)b;
}
Run Code Online (Sandbox Code Playgroud) 这实际上是我感到困惑的一个面试问题的一部分.
class A
{
public A()
{
System.out.println("A") ;
}
}
class B extends A
{
public B()
{
System.out.println("B") ;
}
}
A a1 = new B();
System.out.println() ;
A a2 = (A) new B() ;
Run Code Online (Sandbox Code Playgroud)
所以问题是打印出来的是什么?
起初我以为它应该打印出来
B
A
B
A
Run Code Online (Sandbox Code Playgroud)
但是在我跑回家后,它给了
A
B
A
B
Run Code Online (Sandbox Code Playgroud)
我理解它是继承,然后将B向上转换为A,它也是合法的语法,但为什么B之前的A打印?
我有一个简单的类层次结构,我有一个覆盖的虚方法.但在某些调用中我想调用此方法的基类版本而不是虚方法.
例如:
public class A {
public virtual void Foo() {...}
}
public class B : A {
public override void Foo() {...}
}
public class Program {
public void SomeMethod()
{
...
// ListofA is type IEnumerable<A>
foreach (var item in ListofA)
{
// I want this to call A.Foo(), rather than B.Foo()
// But everything I've tried, which has really just been casting, has resulted in B.Foo()
item.Foo();
}
}
}
Run Code Online (Sandbox Code Playgroud) 当我们在base以及派生类中声明方法为static并进行upcasting时,为什么它调用基类方法.
class Base
{
static void show(){
System.out.println("Base class....");
}
}
class Derive extends Base
{
static void show(){
System.out.println("Drive class....");
}//method hidding.....
public static void main(String[] args)
{
Base b= new Derive();
b.show();
}
}
Run Code Online (Sandbox Code Playgroud) 我只是想知道如何使用子类来实现超类,例如.
class Animal {
void poo() {
System.out.println("general poo");
}
}
class Horse extends Animal{
void poo() {
System.out.println("horse poo");
}
}
Animal animal1 = new Horse();
// using this I get the implementation of the Horse class's methods
animal1.poo(); //should return horse poo
Run Code Online (Sandbox Code Playgroud)
试图升级它以获得超级类实现,但无济于事
((Animal)animal1).poo() // still returns the horse class's implementation of the method
Run Code Online (Sandbox Code Playgroud)
如何使用animal1对象获取超类实现?
我将以下代码中的Model2实例上转换为Object类,然后在Model1类的测试方法中向下转换回类-Model2 。但是thenUov在向下转换后其属性值显示为null。实例在Upcasting-then-Downcasting之后松开其状态时,是否期望这样做?能否请您分享一些细节。另外,是否有一种方法可以在上传后保留实例的状态?
public class Demo{
public static void main(String[] args) {
Model1 m1 = new Model1();
m1.setAttr1(10);
Model2 m2 = new Model2();
m2.setAttr2(10);
m1.test(m2);
}
}
class Model1 {
private Integer attr1;
public Integer getAttr1() {
return attr1;
}
public void setAttr1(Integer attr1) {
this.attr1 = attr1;
}
public void test(Object o) {
Model2 m = (Model2) o;
System.out.println(m.getAttr2());
}
}
class Model2 {
private Integer attr2;
public Integer getAttr2() {
return attr2;
}
public void setAttr2(Integer attr1) …
Run Code Online (Sandbox Code Playgroud) upcasting ×8
java ×5
downcast ×3
c++ ×2
inheritance ×2
c# ×1
casting ×1
class ×1
constructor ×1
oop ×1
pointers ×1
types ×1
unique-ptr ×1