1.基本概念:
对象:自包含的实体 用一组可识别的特性和行为来标识oop 面向对象编程 object-oriented programming
类:是一组具有相同属性和行为对象的抽象集合
构造方法:创建实例的方法
方法重载:重写父类的方法
属性访问修饰符:对方法 属性的访问权限 包括public protected private等
2.面向对象四大特性
(1)封装 如果多个对象具有相同的属性 操作 可以将这些属性 操作抽象出一个类 这个过程被称之为 封装。
封装的好处:1.减少耦合度 2.内部实现可以自由修改 3.类具有清晰的对外接口。
(2)继承
对象的继承描述的是一种isa的关系。如果两个对象A和B 可以描述为B是A。那么表明B可以继承A。
还可以这么理解,继承者被理解为被继承者的特殊化 除了具备被继承者的特性之外 还具备自己独有的特性。
继承定义了类如何相互关联。继承的工作方式是 定义父类和子类 或叫做基类和派生类 其中子类继承父类的所有特性,子类不但继承了父类的所有特性 还可以自定义新的特性。
学习继承记住的三句话:
如果子类继承于父类 那么:
1.子类拥有父类非private的属性和功能
2.子类具有自己的属性和功能 即子类可以扩展父类没有的属性和功能。
3.子类可以重写父类的方法。
protected访问修饰符修饰的成员变量/方法 可以被子类完全继承 用protected修饰的变量/方法 对子类开放而对外界封闭。
以两个类cat,dog为例 当前对象中含有的相同的属性 name age等和shout方法可以被抽象出来 封装到一个animal类中。子类继承自animal 就可以继承父类的非private方法了。
简单的继承减少了代码冗余增加了可复用性。
而且有一点,在很多的对象的场合,不继承,如果需求变更所有的代码都需要修改。并且出错的可能性越大
抽象出父类的话,如果要修改的话只需要修改父类的代码
总结出一句话 继承使得子类的扩展 修改都较容易。
但是 继承对于一些状况是不使用的。如 dog类继承自cat类。如果给cat类增加抓老鼠的方法 那么子类dog也会抓老鼠了。这里说明继承是有缺点的 就是父类变化 子类必须变化 继承会破坏封装 父类的实现细节暴漏给子类。这其实增加了耦合性。
继承是一种类与类之间强耦合的关系。不能乱用 只有当is-a的情况考虑使用继承。
(3)多态
在以上的需求中添加新的需求。cat dog添加叫的方法 shout 继承自animal的父类
那么我需要在子类实现父类的shout方法,各自有各自的实现。
多态:是指不同的对象可以执行相同的操作。但是方法的执行与类内实现有关。
多态的特点:
1.子类以父类的身份出现
2.子类在工作时以子类的方式实现
3.子类以父类的身份出现时 自己的方法不可使用。
小例子:儿子冒充父亲上台表演。
儿子以父亲的身份出现
儿子演出的内容和父亲相同但是演的是自己的技巧
儿子自己的技术不能演
那么多态怎么使用呢?
父类写成抽象类,方法声明为抽象方法 被子类继承且重写。
oc中的多态:
1.oc中所有成员函数都是虚函数
2.父类指针指向子类对象
3.调用的时候只看指针而不看对象。
多态的方法调用原理:当方法被调用时 无论对象是否被转换为父类对象 执行方法时都是位于对象继承链最末端的方法被调用。即:抽象方法是按照运行时类型而非编译时类型被动态绑定调用的。
3.重构 改善现有代码的设计
如果现在需要添加功能 如需要添加牛和羊 怎么做?普遍方式:实现两个类 继承自animal类。
都含有shout方法 但是当前的所有的类都需要添加shout方法 所以具有了重复的代码。如果需要修改这方法中的方法 那么我们必须修改所有类的方法。
妥善方法:抽象出这个方法,animal类中添加shout方法
但是这样我无法获取动物叫的声音。于是 我们需要给定一个方法 getShoutSound在实现中
shout
{
getShoutSound();
return;
}
就可以了。
细节:得到叫声 是一个虚方法 是子类必须重写的代码 且不能被其他类所访问。于是给定修饰符 protected
这时候 子类中除了叫声 构造方法不同之外 所有的重复代码都放在了父类
调用时 子类继承自父类的非private方法直接调用就可以。
这就是一个设计模式----模版模式。
4.抽象类
oc中有抽象类的概念 但是没有抽象类的实现。用protocol的方式 父类引入协议 实现其中的方法 子类就可以继承父类的方法了。
在c++中abstract修饰符修饰的类是抽象类
1.抽象类无法实例化
2.抽象方法是必须被子类重写的方法
3.如果类中包含抽象方法 那么这个类必须定义为抽象类 不论是否还包含其他的一般方法。
什么时候使用抽象类呢?
抽象类通常代表一个抽象概念 它提供一个继承的出发点 当设计一个新的抽象类时一定是用来继承的 所以 在一个以继承关系形成的等级结构里面 树叶节点应当是具体类 而树枝节点应当是抽象类。
即 具体类不适用继承。
5.接口
增加需求 动物的特殊功能的展现
比较叮当 孙悟空 猪八戒的本领大 如变化出东西
如果我们一味地将 变出东西 作为一个方法 并封装到animal抽象类中 那么其他动物其实是不具备这个方法的。这个时候需要用到接口。
接口是把隐式公共方法和属性组合起来 以封装特定功能的一个集合 一旦类实现了接口 类就可以支持接口所指定的所有属性和成员。声明接口在语法上与声明抽象类完全相同,但不允许实现接口中任何方法。所以接口不能实例话 不能有构造方法 字段,不能有修饰符 比如public private等等。不能声明虚拟 静态。
还有就是实现接口的类就必须实现接口中所有方法和属性。
虽然麻烦 但是一个类可以支持多个接口 多个类也可以支持相同的接口 所以接口的概念可以让用户和其他开发人员更容易理解其他人的代码。
那么抽象类和接口有什么区别?
从形态上分:
1.抽象类可以给出一些成员的实现 接口却不包含成员的实现
2.抽象类的抽象成员可以被子类部分实现 接口的成员需要实现类完全实现
3.一个类只能继承一个抽象类 但是可以实现多个接口。
还有,1.类是对象的抽象 抽象类是对类的抽象,接口是对行为的抽象
2.如果行为跨越不同类的对象 可以使用接口 对于相似的类对象 使用继承抽象类。
3.从设计的角度讲 抽象类是从子类中发现了公共的东西 泛化出父类 然后子类继承父类 而接口是根本不知道子类的存在,方法如何实现还不确认 预先定义了。
6.集合
数组:连续存储 遍历速度快
NSSet 集合
涉及到装箱和拆箱的操作
装箱:把值类型打包到Object引用类型的一个实例中 比如整形变量i被装箱并赋值
拆箱:从对象中提取值类型
相比简单赋值 这两个过程需要进行大量计算 对值类型进行装箱时 必须分配并构造一个全新的对象 其次拆箱所需强制转换也需要进行大量计算
7.范型
集合的指定类型的形式表现。java中尤其常见。
8.代理
委托 事件 之后再讲。