文档章节

黑马程序员-6-Objective-C学习笔记(OC类的认识)

 明天过后1
发布于 2014/09/30 22:49
字数 2262
阅读 39
收藏 0

---------------------- Java培训.Net培训Android培训IOS培训、期待与您交流! ----------------------

注: 以下代码均为了省事,没有加入内存管理代码

1. 类

                之前已经了解了面向对象的思想了,在OOP中我们关注的重点是对象,那么接下来我们如何来得到我们想要的对象呢?日常生活中,以汽车为例,如果想得到一辆汽车首先要得到该汽车的设计图纸,然后根据图纸来            制造生产汽车,在编程中类相当于设计图纸,编译器相当于生产类的工厂,有了图纸有了工厂我们可以生产成千上万个类来使用。


2. 类的声明和实现

    /***************** car.h *****************/
    #import <Foundation/Foundation.h>    // 如果要使用OC面向对象的特性必须依赖于该框架
    
    // 类的声明
    @interface Car : NSObject            // @interface是告诉编译器这是类的声明的开始
    {                                    // : NSObject 声明该类继承与NSObject,NSObject是所有对象的根类它具备对象的实例化能力
    
        @public                          // @public 说明属相的访问权限为公有,就是可以通过指针来直接访问变量
                                         // @protected 如果不写则默认为 @protected 对于子类公开,就是子类方法中可以访问父类的属性
                                         // @package 只要处在同一个框架中,就能直接访问对象的成员变量
                                         // @private : 只能在当前类的对象方法中直接访问(@implementation中默认是@private)
        
        int _wheels; // 多少个轮子
        int _speed; // 时速
    }
    - (void)run; // 跑的行为
    @end                                 // @end是告诉编译器类声明完毕
    
    /***************** car.m *****************/
    #import "car.h"
    // 类的实现
    @implementation Car                  // @implementation告诉编译器类的实现开始
    - (void) run
    {
        NSLog(@"%i个轮子,%i时速的车子跑起来了", _wheels, _speed);
    }
    @end                                // @end类的实现结束
    
     /***************** main.h *****************/
    #import "car.h"
    
    int main(){
        Car *c = [Car new];
        c->_wheels = 4;
        c->_speed = 150; 
        [c run]; // 4个轮子,150时速的车子跑起来了
        return 0;
    }


3. @interface和@implementation 的分工和好处

    (1) 我们知道在C语言中函数一般我们提供函数的声明和实现,如果要调用该函数需要include该函数的头文件。

    (2) 在类中的@interface相当于函数的声明,用来告诉调用者该类的总体结构,和提供哪些功能。

    (3) 在@implementation中我们一般会把类的一些方法实现,一般这些细节的东西都不会对外公开的。

    (4) @interface 相当于一个产品的框架 ,@implementation相当于把该框架填充,可以用一下图来形象的表示(该图引自苹果官方文档)

            

    (5) 这样做的好处 : 

            1) 维护性好,如果某天要更改需求需要改变类的某个方法的实现,我们只需要更改该类的实现部分即可。

            2) 有利于版本升级,对于@implementation文件我们可以随着版本的升级提供不同版本的文件

            3) 清晰明了,调用者如果想快速了解该类只需要快速浏览该类的@interface文件,如果把声明跟实现写在同一个文件中将增加读取该类的难度。


4. 类编写的一些规范

    a. 属性命名规范

            (1) 属性命名要尽量有意义,而且尽量使用英文名词单词,对于复合单词用驼峰标识

            (2) 属性命名以下划线 _ 开头,在OC中一般以下划线来标识类的属性

            (3) 为了更好的可读性一般在属性定义后面加上注解(可选)。

    b. 属性的 settter 和 getter

            (1) setter :  - (void) set属性名(首字母大写去掉下划线):(属性类型)形参名称 ;

            (2) getter : - (属性类型) 属性名称(去掉下划线) ;

    // car.h
    #import <Foundation/Foundation.h>
    @interface Car : NSObject 
    { // 属性要写在大括号内
        int _wheels; // 多少个轮子
        int _speed; // 时速
    }
    - (void) setWheel:(int) wheel;
    - (int) wheel;
    - (void) setSpeed:(int) speed;
    - (int) speed;

    c. 方法的命名规范

            (1) - 代表对象方法 , + 代表类方法。对象方法调用依赖于类,类方法依赖于类

            (2) 声明和使用:

    // Car.h
    #import <Foundation/Foundation.h>
    #import "Person.h"
    @interface Car : NSObject 
    { // 属性要写在大括号内
        int _wheels; // 多少个轮子
        int _speed; // 时速
    }
    - (void) setWheel:(int) wheel;
    - (int) wheel;
    - (void) setSpeed:(int) speed;
    - (int) speed;
    // 一个人启动一辆车
    - (BOOL) startBy: (Person *) person;            // - 对象方法; (BOOL) 返回值类型 ; startBy: 方法名 ; (Person *) 参数类型 ; person 参数名称
    + (void) introduce;                             // + 类方法
    
    // Car.m
    ...
    
    // main.m
    
    #import "Car.h"
    #import "Person.h"
    int main(){
        [Car introduce];                            // 调用类方法
        Car *c = [Car new];                         // 对象的创建
        Person *p = [Person new];
        BOOL b = [c startBy: p];                    // 对象方法调用
        NSLog("start %@"( b ? @"success" : @"failed"));
        return 0;
    }


5. 一些注意地方

    a. 语法方面注意点 

           (1) 成员变量不能在{}中进行初始化、不能被直接拿出去访问

           (2) 方法不能当做函数一样调用

           (3) 成员变量\方法不能用static等关键字修饰,别跟C语言混在一起(暂时忽略)

           (4) 类的实现可用写在main函数的后面,主要在声明后面就行了

    b. 方法注意点

            (1) OC方法只能声明在@interface和@end之间,只能实现在@implementation和@end之间。也就是说OC方法不能独立于类存在

            (2) C函数不属于类,跟类没有联系,C函数只归定义函数的文件所有

            (3) C函数不能访问OC对象的成员

            (4) 低级错误:方法有声明,但是实现的时候写成了函数

            (5) 方法只有声明,没有实现(经典错误)

            (6) 方法没有声明,只有实现(编译器警告,但是能调用,OC的弱语法)

            (7) 编译的时候:访问没有的成员变量直接报错,访问没有的方法,只是警告


6. self 关键字

    a. self 初步认识

        在 java 和 C++ 中有 this 指针指向当前对象,因此我们可以通过 this 指针来访问该对象的成员变量和方法,一般该指针只限制于该对象的内部使用。OC 提供了self 关键字那么该关键字与this指针是否有相同的作用    呢?答案是否,该关键字指向的是调用者本身,那么该关键字可以用于对象方法(类似于java中的静态方法)中,但在 java 中this指针不能用于静态方法。

    b. 如何使用

    // Number.h
    #import <Foundation/Foundation.h>
    
    @interface Number: NSObject 
    {
        int _value;
    }
    - (void) setValue:(int)value;
    - (int) value;
    
    - (int) addWith:(Number *)num;
    + (int) num1:(Number *)n1 addWith:(Number *)n2;
    + (void) printAddResultWith:(Number *)n1 and:(Number *)n2;
    @end 
    
    // Number.m
    #import "Number.h"
    
    @implementation Number
    - (void) setValue:(int)value
    {
        self -> _value = value;                        // 在对象方法中self指向当前对象,因此可以通过该指针来访问成员变量
       
        // [self setValue:value];                     // 在某个方法中不能使用self调用该方法否则会引发死循环
    }
    - (int) value
    {
        return _value;
    }
    
    - (int) addWith:(Number *)num                        
    {
        return [self value] + [num value];             // 在对象方法中self指向当前对象,分别通过self指针访问成员变量 和 通过对象访问成员变量
    }
    
    + (int) num1:(Number *)n1 addWith:(Number *)n2
    {
        return [n1 value] + [n2 value];                
    }
    
    + (void) printAddResultWith:(Number *)n1 and:(Number *)n2
    {
        NSLog(@"the result is: %d"[self num1:n1 addWith:n2]);    // 在类方法中self指向当前类对象,因此它可以调用该类对象的类方法
    }
    @end


7. super关键字

    a. super初步认识

            同样在java中也有super关键字,不过要注意区分的地方跟 self 和 java中的this一样,super指向的是调用者父类的相应对象:

            对象方法 中 super 指向 的 父类对象 ,因此我们可以通过super关键字调用父类中的相应对象方法。

            类方法 中 super指向的是 父类的类对象 ,因此我们可以通过super关键字调用父类中相应的类方法。

    b. 如何使用

    /*
         Person.h
    */
    #import <Foundation/Foundation.h>
    
    @interface Person: NSObject
    {
        int _age;
    }
    - (void) setAge:(int)age;
    - (int)age;
    + (id) initWithAge:(int)age;                        // 声明一个构造方法返回一个OC对象的万能指针
    + (void) ageDesciption(Person *)p;
    @end
    
    /*
        Person.m
    */
    #import "Person.h"
    @implementation Person
    - (void) setAge:(int)age
    {
        self->_age = age;
    }
    - (int)age
    {
        return _age;
    }
    
    + (id) initWithAge:(int)age                        // 构造方法实现
    {
        id p = [[Person alloc] init];
        [p setAge:age];
        return p;
    }
    
    + (void) ageDesciption(Person *)p
    {
        if ( [p age] < 18 )
        {
            NSLog("青少年一个");
        } else {
            NSLog("非青少年");
        }
    }
    @end
    
    /*
             Student.h
     */
    #import "Person.h"
    
    @interface Student : Person                            // Student继承与Person类将拥有父类的属性和方法
    {
        NSString *_name;
    }
    - (void) setName:(NSString *)name;
    - (NSString *)name;
    + (id) initWithName:(NSString *)name andAge:(int)age;    // 声明一个构造方法
    + (void) introduceHimself;
    @end
    
    /*
             Student.m
     */
    #import "Student.h"
    
    @implementation Student
    
    - (void) setName:(NSString *)name
    {
        _name = name;
    }
    - (NSString *)name
    {
        return _name;
    }
    
    + (id) initWithName:(NSString *)name andAge:(int)age    // 构造方法实现
    {
        id s = [super age];                                // super当前指向Student类对象的父类对象
        [s setNmae:name];
        return id;
    }
    
    - (void) introduceHimself
    {
        int age = [super age];                            // super指向当前对象的父类对象
        NSLog("my name is %@, age is %d",_name,_age);
    }
    @end
    
    /*
        main.m
     */
     #import "Student.h"
     
     int main(){
     
        Student *s = [Student initWithName:@"jack" andAge:20];
        [s introduceHimself];
         return 0;
     }



---------------------- Java培训.Net培训Android培训IOS培训、期待与您交流! ---------------------- 

 详情请查看:http://edu.csdn.net/heima



© 著作权归作者所有

共有 人打赏支持
粉丝 2
博文 23
码字总数 36166
作品 0
佛山
私信 提问
一、Objective-C概述

说明:这个Objective-C专题,是学习iOS开发的前奏,也为了让有面向对象语言开发经验的程序员,能够快速上手Objective-C。如果你还没有编程经验,或者对Objective-C、iOS开发不感兴趣,请忽略...

长平狐
2013/03/28
128
0
Objecitive-C中的nil

当我学习OC的时候,我总是忍不住在对比。Actionscript是如何实现,而oc又是如何实现。这不,碰到nil的时候我发现了很大的不同之处。做个笔记。 在as中,如果将一个对象置为null,相当于空指针...

ChildhoodAndy
2013/03/21
0
3
OC学习之旅 (一) 内存管理及OC常用方法

最近学习OC,所以在博客写下自己的笔记. OC的基本: 1 id 相当于java的Object 代表任何对象. 所以id是关键字,不能用作变量!! 2 oc中使用"."符号是调用 int a =object.a 是调用的是 [object ge...

Jonson
2013/04/13
0
2
iOS开发初学者如何入门?

iOS开发初学者如何入门? 现在如何学习iOS开发成为很多人的疑问,事实上,并不是想象中的那样难,学习iOS开发从最根本的一点上去思考就是,把iOS培训的知识按区块分开,更加便于学习,现在很多...

红牛王
2017/05/23
59
0
iOS - Swift 与 Objective-C 互相操作

https://www.cnblogs.com/QianChia/p/5777341.html#_label2 本文目录 前言 1、在 Swift 中使用 Objective-C、C 代码 2、在 Objective-C 中使用 Swift 代码 回到顶部 前言 在 Swift 语言中,我...

壹峰
2018/01/15
0
0

没有更多内容

加载失败,请刷新页面

加载更多

dotConnect for Oracle入门指南(六):使用事务

【下载dotConnect for Oracle最新版本】 dotConnect for Oracle(原名OraDirect.NET)建立在ADO.NET技术上,为基于Oracle数据库的应用程序提供完整的解决方案。它为设计应用程序结构带来了新的...

电池盒
6分钟前
0
0
Spring Batch JSR-305 支持

本发布版本中为 JSR-305 支持添加了一个注解。这个为了与 Spring 框架中的 Null-safety 注解取得平衡,然后为 Spring Batch 添加为 public APIs。 这个注解不仅仅在使用 Spring Batch APIs ...

honeymoose
7分钟前
0
0
React Native工程中TSLint静态检查工具的探索之路

背景 建立的代码规范没人遵守,项目中遍地风格迥异的代码,你会不会抓狂? 通过测试用例的程序还会出现Bug,而原因仅仅是自己犯下的低级错误,你会不会抓狂? 某种代码写法存在问题导致崩溃时...

美团技术团队
9分钟前
0
0
mysql update select

在遇到需要update设置的参数来自从其他表select出的结果时,需要把update和select结合使用,不同数据库支持的形式不一样,在mysql中如下: update A inner join(select id,name from B) c on A.i...

张欢19933
12分钟前
0
0
KaliLinuxNetHunter教程刷入第三方Recovery与开始刷机

KaliLinuxNetHunter教程刷入第三方Recovery与开始刷机 2.刷入第三方Recovery(即TWRP) TWRP(TeamWin Recovery Project)是一款XDA大神开发的一款全触屏操作的第三方Recovery。支持滑动确认...

大学霸
15分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部