我想检查对象(例如someObject
)是否可分配(可铸造)到另一种类型的变量(例如SpecifiedType
).在Java中,我可以写:
someObject instanceof SpecifiedType
Run Code Online (Sandbox Code Playgroud)
一个相关的问题是查找对象的运行时类型是否等于另一种类型.在Java中,我可以写:
someObject.getClass().equals(SpecifiedType.class)
Run Code Online (Sandbox Code Playgroud)
如何在Objective-C中完成?
对于类变量,向上铸造和向下铸造有什么区别?
例如,在下面的程序类中,Animal只包含一个方法但Dog类包含两个方法,那么我们如何将Dog变量转换为Animal变量.
如果完成了施法,那么我们如何使用Animal的变量调用Dog的另一种方法.
class Animal
{
public void callme()
{
System.out.println("In callme of Animal");
}
}
class Dog extends Animal
{
public void callme()
{
System.out.println("In callme of Dog");
}
public void callme2()
{
System.out.println("In callme2 of Dog");
}
}
public class UseAnimlas
{
public static void main (String [] args)
{
Dog d = new Dog();
Animal a = (Animal)d;
d.callme();
a.callme();
((Dog) a).callme2();
}
}
Run Code Online (Sandbox Code Playgroud) 在Swift中给出以下内容:
var optionalString: String?
let dict = NSDictionary()
Run Code Online (Sandbox Code Playgroud)
以下两个陈述之间的实际区别是什么:
optionalString = dict.objectForKey("SomeKey") as? String
Run Code Online (Sandbox Code Playgroud)
VS
optionalString = dict.objectForKey("SomeKey") as! String?
Run Code Online (Sandbox Code Playgroud) 我是C#(和OOP)的新手.当我有一些如下代码:
class Employee
{
// some code
}
class Manager : Employee
{
//some code
}
Run Code Online (Sandbox Code Playgroud)
问题1:如果我有其他代码执行此操作:
Manager mgr = new Manager();
Employee emp = (Employee)mgr;
Run Code Online (Sandbox Code Playgroud)
这Employee
是一个Manager
,但当我把它这样投射到Employee
它意味着我正在向上倾斜它?
问题2:
当我有几个Employee
类对象时,有些但不是全部都是它们Manager
,我怎么能在可能的情况下将它们转发?
考虑:
struct SomethingThatsABase
{
virtual bool IsChildOne() const { return false; }
virtual bool IsChildTwo() const { return false; }
};
struct ChildOne : public SomethingThatsABase
{
virtual bool IsChildOne() const { return true; }
};
struct ChildTwo : public SomethingThatsABase
{
virtual bool IsChildTwo() const { return true; }
};
void SomeClientExpectingAChildOne(std::shared_ptr<ChildOne> const& ptrOne)
{
//Does stuff
}
void SomeClient(std::shared_ptr<SomethingThatsABase> const& ptr)
{
if (ptr->IsChildOne())
{
SomeClientExpectingAChildOne(ptr); //Oops.
//Hmm.. can't static_cast here, because we need a `shared_ptr` out of …
Run Code Online (Sandbox Code Playgroud) 我很确定我理解上传和下传之间的一般区别,特别是在C++中.我知道我们不能总是向下转换因为将基类指针强制转换为派生类指针会假定所指向的基类对象具有派生类的所有成员.
在学期的早些时候,我的教授告诉全班同学,在C++中升级有时也是非法的,但我似乎错过了我的笔记中的原因,我不记得这是什么时候发生的.
什么时候在C++中升级是非法的?
我有三个班:
class A {};
class B : virtual public A {};
class C : virtual public A {};
class D: public B, public C {};
Run Code Online (Sandbox Code Playgroud)
尝试从A*到B*的静态强制转换我得到以下错误:
cannot convert from base A to derived type B via virtual base A
Run Code Online (Sandbox Code Playgroud) 请考虑以下代码:
struct Base {};
struct Derived : public virtual Base {};
void f()
{
Base* b = new Derived;
Derived* d = static_cast<Derived*>(b);
}
Run Code Online (Sandbox Code Playgroud)
这是标准([n3290: 5.2.9/2]
)禁止的,因此代码无法编译,因为Derived
实际上是继承自的Base
.virtual
从继承中删除使代码有效.
这条规则存在的技术原因是什么?
我有一个类,可能需要将对象更改为后续级别的后代类.这可能吗?我知道一个选项是返回它的副本但是使用子类,但是实际修改当前对象会很好...所以:
class myClass {
protected $var;
function myMethod()
{
// function which changes the class of this object
recast(myChildClass);
}
}
class myChildClass extends myClass {
}
$obj = new myClass();
$obj->myMethod();
get_class_name($obj); // => myChildClass
Run Code Online (Sandbox Code Playgroud) 我一直在玩Swift并发现当向下投射一个要插入字典的对象时,我得到一个奇怪的警告:Treating a forced downcast to 'String' as optional will never produce 'nil'
.如果我更换as
,as?
则警告消失.
func test() -> AnyObject! {
return "Hi!"
}
var dict = Dictionary<String,String>()
dict["test"]=test() as String
Run Code Online (Sandbox Code Playgroud)
Apple的文档说明如下
由于向下转换可能会失败,因此类型转换运算符有两种不同的形式.可选表单
as?
将返回您尝试向下转换的类型的可选值.强制形式as
尝试向下倾斜并强制将结果作为单个复合动作展开.
我不清楚为什么在这里使用as?
而不是as
正确的.一些测试显示,如果我更改test()以返回Int而不是String,如果我继续使用,代码将退出并出现错误as
.如果我切换到使用as?
那么代码将继续正常执行并跳过该语句(dict将保持为空).但是,我不确定为什么这是更可取的.在我看来,我宁愿程序退出并出现错误并让我知道演员表不成功然后只是忽略错误的声明并继续执行.
根据文档,我应该使用强制形式"只有当你确定转发将永远成功时".在这种情况下,我确信向下转换将永远成功,因为我知道test()
只能返回一个字符串,所以我认为这是强制形式的向下转换的完美情况.那么为什么编译器会给我一个警告呢?