首先是面向对象语言的三大基本特性:封装,继承,多态。
封装:将事物的细节隐藏起来,只对外暴露一个接口以供信任的人调用。一个类就是封装了各种数据和操作这些数据的方法的逻辑实体。
继承:指可以让某个类型的对象获得另一个类型的对象的属性的方法,有很多类有相同的属性或者方法,就把相同的属性或者方法封装到一个类当中作为父类,其他类想要获得这些属性或者方法,就可以继承自他。
多态:是指一个类实例的相同方法在不同情形有不同表现形式:
多态就是父类指针指向子类对象。
关于多态:在编译的时候并不知道要调用的是父类还是子类的方法,运行的时候才会根据实际类型调用子类的方法。
对于结构体来说,因为结构体没有继承,编译的时候就能知道调用哪个方法。
但是对于类,只有在运行的时候才能知道实际调用哪个方法。
class Animal {
func speak() {
print("Animal speak")
}
func eat() {
print("Animal eat")
}
func sleep() {
print("Animal sleep")
}
}
class Dog: Animal {
override func speak() {
print("Dog speak")
}
override func eat() {
print("Dog eat")
}
}
var anim: Animal
anim = Animal()
anim.speak()
anim.eat()
anim.sleep()
anim = Dog()
anim.speak()
anim.eat()
anim.sleep()
面向对象语言可以对事物进行很好的抽象,但是在某些方面实现的不够好,比如:
class human{
var name:String = "fmy"
}
class women: human {
func shopping(){
print("购物")
}
}
class man:human{
func drive(){
print("开车")
}
}
人类是父类,女人和男人是子类。男人可以开车,女人可以购物。
但是后来需求变了,男人也可以购物,女人也可以开车,这个时候该怎么解决?
从面向对象的方法来解决的话:
1.复制粘贴,当然不可取。代码冗余度越来越高,可复用性差
2.在父类里面添加drive和shopping方法,可以是可以,但是这样增加了父类的负担,而且,万一有的类不需要这两个方法咋办?每次遇到这样的事情就往父类里面加,父类越加越大的问题怎么解决?
3.重新定义一个类,往男人类和女人类添加属性创建新定义的类的对象,调用新定义对象的方法:
class human{
var name:String = "fmy"
}
class shop_and_drive{
func shopping(){
print("购物")
}
func drive(){
print("开车")
}
}
class women: human {
var can = shop_and_drive()
}
class man:human{
var can = shop_and_drive()
}
这样也行,不过耦合度提升了,耦合度越高的代码越容易出现内存问题,冗余度越高的代码越不好维护。
4.多继承:swift没这东西,用这东西会有菱形缺陷,也不好。
面向对象没啥好办法解决,这个时候就可以用POP了
康康面向协议的解决办法:
protocol can {
func drive()
func shopping()
}
extension can{
func drive(){
print("开车")
}
func shopping(){
print("购物")
}
}
class human{
var name:String = "fmy"
}
class women: human,can {
}
class man:human,can{
}
协议的扩展功能可以提供默认实现,有了默认实现,遵循协议的类或者结构体就不需要实现。
这样首先:1,冗余度很低吧,万一一个drive或者shopping有几十行呢,很多类都需要这两个方法呢,只需要让类遵循这个协议就可以调用方法了。
2.耦合度不高吧,也没有对其他对象的引用,几乎不用担心循环引用的问题吧。
这只是简单举个例子,冰山一角,真正的POP的思想需要多写代码多做项目去体会。