目标C中的多态性和遗传

时间:2013-06-21 07:26:16

标签: objective-c polymorphism

我在Objective C中有一个编码,想要创建一个基本Controller并使用多态来创建子类。我也在关注CS193p stanford课程。由于多态性使用不同类的通用方法,如果xcode具有相同的函数名,xcode如何知道每个子类要调用哪个函数?

此外,在基类中调用一个函数但返回nil并且有一个注释说抽象。此函数在子类控制器中实现并返回一个值。如果基类控制器在层次结构中较低,它将如何调用子类函数?为什么不归零?

3 个答案:

答案 0 :(得分:18)

<强>多形性:

Objective-C中的多态性是您在大多数基于类的面向对象语言中找到的相当标准的子类型多态性。这意味着类的实例也可以被视为其任何超类的实例。

更具体地说,这意味着我们可以调用MyCustomTableViewCell的自定义UITableViewCell子类可以在任何需要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

<强>参考文献:

http://www.quora.com/In-Objective-C-what-is-polymorphism

http://www.techotopia.com/index.php/Objective-C_Inheritance

答案 1 :(得分:0)

当一个类继承自另一个类并实现也在超类中实现的函数时,它会覆盖超类中的实现。您这样做是为了添加超类中不存在的行为。通常你也会调用超类中的函数。 当您从另一个对象调用该函数时,将调用最深的超类中的函数。这被称为多态性。如果它不能以这种方式工作,您将永远无法向类添加功能。

有些人可以帮助我理解这个原则。

//  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

答案 2 :(得分:0)

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中,你说“向对象发送消息”而不是“调用类的功能”来强调这一事实。

Check out the Apple docs on the gory details of messaging and inheritance!