我在 Objective C 中有一个编码,想要制作一个基本控制器并使用多态性来创建子类。我也在关注 CS193p 斯坦福课程。由于多态性对不同的类使用通用方法,如果它们具有相同的函数名,xcode 如何知道每个子类中的哪个函数要调用?
此外,在基类中调用了一个函数,但返回 nil 并有一个注释说抽象。该函数在子类控制器中实现并返回一个值。如果层次结构较低,基本控制器怎么会调用子类函数?为什么它不返回零?
我在 Objective C 中有一个编码,想要制作一个基本控制器并使用多态性来创建子类。我也在关注 CS193p 斯坦福课程。由于多态性对不同的类使用通用方法,如果它们具有相同的函数名,xcode 如何知道每个子类中的哪个函数要调用?
此外,在基类中调用了一个函数,但返回 nil 并有一个注释说抽象。该函数在子类控制器中实现并返回一个值。如果层次结构较低,基本控制器怎么会调用子类函数?为什么它不返回零?
多态性:
Objective-C 中的多态是您在大多数基于类的面向对象语言中找到的相当标准的子类型多态。这意味着一个类的实例也可以被视为它的任何超类的实例。
更具体地说,这意味着您的自定义 UITableViewCell 子类(我们将其称为 MyCustomTableViewCell)可以在任何需要 UITableViewCell 的地方使用。如果方法具有 UITableViewCell 参数,则可以传递 MyCustomTableViewCell 的实例。
反之则不正确;如果方法需要 MyCustomTableViewCell 的实例,则传递常规 UITableViewCell 是错误的。
这是因为子类继承了它们超类的接口。MyCustomTableViewCell 自动拥有 UITableViewCell 的所有方法(如 prepareForReuse)。方法实现可能会被覆盖,但您仍然可以向它发送相同的消息。
请记住,将 MyCustomTableViewCell 的实例视为 UITableViewCell 不会改变其行为。如果你已经覆盖了 prepareForReuse,你仍然会得到你被覆盖的行为。
遗产:
继承的概念为编程带来了一些真实的世界观。它允许定义具有特定特征集(例如方法和实例变量)的类,然后创建从该类派生的其他类。派生类继承父类的所有特性,然后通常添加自己的一些特性。
通过派生类,我们创建了通常称为类层次结构的东西。层次结构顶部的类称为基类或根类,派生类称为子类或子类。一个类可以派生出任意数量的子类。派生出子类的类称为父类。
类不仅需要从根类派生。例如,一个子类也可以从另一个子类继承,从而有可能创建大而复杂的类层次结构。在 Objective-C 中,子类只能从单个直接父类派生。这是一个称为单一继承的概念。
教程:
http://www.tutorialspoint.com/objective_c/objective_c_inheritance.htm
http://www.tutorialspoint.com/objective_c/objective_c_polymorphism.htm
参考:
Xcode 不知道类型的对象(实际上是指针)UIViewController
是否实际上指向子类类型的对象,例如MyViewController
. 这将在运行时计算出来。
在您的程序中的某个时刻,您将不得不“ alloc init
”您的MyViewController
,这就是为类型对象保留一点内存的时候MyViewController
。之后你可以让一个类型的对象UIViewController
指向那块内存,但内存本身不会改变。UIViewController
如果在基类和子类中都定义了一个函数,MyViewController
则称该函数被覆盖,并且该信息也包含在该位内存中。
使用此代码段,您可以检查对象及其函数的内存地址:
MapViewController *m = [[MapViewController alloc] init];
NSLog(@"MapViewController at memory location %p with function loadView %p", m, [m methodForSelector:@selector(loadView)]);
UIViewController *v = m;
NSLog(@"UIViewController at memory location %p with function loadView %p", v, [v methodForSelector:@selector(loadView)]);
UIViewController *v2 = [[UIViewController alloc] init];
NSLog(@"UIViewController at memory location %p with function loadView %p", v2, [v2 methodForSelector:@selector(loadView)]);
如果函数未在子类中定义,则将调用基类(继承链中更高的一个类)的函数。
此外,在objective-c中,您说“向对象发送消息”而不是“调用类的函数”来强调这一事实。
当一个类从另一个类继承并实现也在超类中实现的功能时,它会覆盖超类中的实现。您这样做是为了添加超类中不存在的您需要的行为。通常你也会调用超类中的函数。当您从另一个对象调用函数时,将调用来自最深超类的函数。这就是所谓的多态性。如果它不能以这种方式工作,您将永远无法向类添加功能。
下面的一些可以帮助我理解原理。
// In pseudo code
class Figure
def area
return length * width
end
end
class Rectangle < Figure
// Don't need to add a different area calculator, the default is good
end
class Circle < Figure
def area
return PI * radius *radius
end
end
figures = [Circle.new .., Rectangle.new .. ]
// Now loop over all the figures, we are not interested in what figures exactly are
figures.each do |figure|
total_area = total_area + figure.area
end