zoukankan      html  css  js  c++  java
  • Objective-c 总结(一):OC类的设计

    (一)学习目标:

    1.面向对象基本概念:

    OOP的主要思想是把构成问题的各个事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描述一个事物在整个解决问题步骤中的行为。

    2.熟悉OC类的定义:

    OC类分为两个文件,.h 和 .m文件

    .h 文件存放类、函数声明,类声明用关键字@interface @end 来声明

    .m文件存放的是具体实现,类实现使用关键字@implementation @end 来实现

    + 表示类的方法,相当于 JAVA中的静态函数

    -  表示对象方法,对象实例化可以调用

    3.熟悉OC的字段定义:

    @interface Person : NSObject
     {
          int age;  //字段在此定义
     }
     - (void)setAge:(int)newAge; //函数在此定义
     @end
    
    -(int) f:(int)x
    函数模型从左到右说明
    1、-或+表示对象函数或类函数,
    2、(int)表示返回值
    3、f:表示函数名称
    4、(int)x表示函数形参
    
    变量申明:@public @protected @private
    
      O-C中变量必须定义在类{}之间的地方
    
      O-C缺省是@protected
    
      O-C里面的函数全是@public类型 没有其他的类型(用另外的方式实现private化)
    
    创建对象
    
      Dog *dog=[Dog alloc];
    
      初始化构造函数
    
      [dog init];
    
      销毁对象
    
       [dog release];
    
    OC有别于C/C++的一些比较
    
      1、BOOL  YES  NO
    
       在oc中布尔类型是BOOL,布尔值是yes,no
    
      2、id类型
    
        O-C中每个目标都可以表达为id类型,可以认为是NSObject*或者是void*
    
      3、nil
    
        nil表示null,表示一个目标指针
    
      • 函数类型 C++ Object-C
        无参数 int say();
        int res = obj->say();
        -(int) say;
        int res = [obj say];
        一个参数 int say(int a);
        int res = obj->say(1);
        -(int) say:(int)a;
        int res = [obj say:1];
        两个参数 int say(int a,int b);
        int res = obj->say(1,3);
        -(int) say:(int)a :(int)b;
        int res = [obj say:1 :3];
        带标签 int sayAndWrite(int a,int b);
        int res = obj ->sayAndWrite(1,3);
        -(int) say:(int)a andWrite:(int)b;
        int res = [obj say:1 andWrite:3];

    4. 熟悉OC函数定义的规则:

    - (void) doIt:(NSString *) actorName movieName: (NSString*) value timesSeen: (int)times { 
    NSLog(@"%@ is my favorite actor in the movie %@, I saw it %i times.",actorName, value, times); 
    }

    1、'-'表示这个函数是实例函数(类似非静态函数),'+'表示这个函数是类函数(类似静态函数)
    2、(void)表示这个函数没有返回值。
    3、函数名是'doIt: movieName: timesSeen:',而不是'doIt'
    4、参数用空格隔开
    5、参数类型写在括号中
    6、参数分内部参数和外部参数,如电影名称,内部参数是:value,外部参数是:movieName

    5.+函数与-函数有什么不同?

    +函数类方法,-函数实例方法

    类方法,也称静态方法,指的是用static关键字修饰的方法。此方法属类本身的方法,不属于类的某一个实例(对象)。类方法中不可直接使用实例变量。其调用方式有三种:可直接调用、类名.方法名、对象名.方法名。实例方法指的是不用static关键字修饰的方法。每个实例对象都有自身的实例方法,互相独立,不共享一个。其调用方式只能是对象名.方法名。 

           用修饰符static声明的方法为静态方法,不用修饰符static声明的方法为实例方法。不管类生成或未生成对象,类的静态方法都可以被使用,使用格式为:类名.静态方法名。静态方法只能使用该静态方法所在类的静态数据成员和静态方法。这是因为使用静态方法时,该静态方法所在类可能还没有对象,即使有对象,由于用类名.静态方法名方式调用静态方法,静态方法没有this指针来存放对象的地址,无法判定应访问哪个对象的数据成员。在类创建对象后,实例方法才能被使用,使用格式为:对象名.实例方法名。实例方法可以使用该方法所在类的所有静态成员和实例成员。
    何时用静态方法,何时用实例方法?
    先说实例方法,当你给一个类写一个方法,如果该方法需要访问某个实例的成员变量时,那么就将该方法定义成实例方法。一类的实例通常有一些成员变量,其中含有该实例的状态信息。而该方法需要改变这些状态。那么该方法需要声明成实例方法。

    静态方法正好相反,它不需要访问某个实例的成员变量,它不需要去改变某个实例的状态。我们把该方法定义成静态方法。

    关于静态方法和实例方法的一些误区。

    静态方法常驻内存,实例方法不是,所以静态方法效率高但占内存。
    事实上,方法都是一样的,在加载时机和占用内存上,静态方法和实例方法是一样的,在类型第一次被使用时加载。调用的速度基本上没有差别。


    静态方法在堆上分配内存,实例方法在堆栈上。

    (二)讲义内容:

    1. NSLog 使用:

    1、NSLog会自动加上换行符,不需要自己添加换行符,NSLog会加上时间和进程信息,而printf仅将输入的内容输出不会添加任何额外的东西。

    2、打印字符串

    NSLog(@”hello , Objective-C !”);

    3、c字符串是字符串数组,NSString字符串是oc对象,不能动态更改。

    2. 定义一个类:

    类的.h 和 .m 概念:

    .h :头文件。头文件包含类,类型,函数和常数的声明。 
    .m :源代码文件。这是典型的源代码文件扩展名,可以包含Objective-C和C代码。 
    .mm :源代码文件。带有这种扩展名的源代码文件,除了可以包含Objective-C和C代码以外还可以包含C++代码。仅在你的Objective-C代码中确实需要使用C++类或者特性的时候才用这种扩展名

    如何定义一个类:

    创建对象
    Dog *dog=[Dog alloc] ; 一个类的名字 + alloc
    初始化构造函数
    [dog init];    凡是以init…开头的都是构造函数
    销毁对象
    [dog release];

    创建一个 OC 类需要编写两个部分  @interface@implementation
    
    @interface 专门用于类的描述,描述的内容包括:实例变量的名称和类型,以及实例变量的方法,当然了,在描述“方法”的时候是会指明它的名称,是否具有返回值,是否用到参数等等。例如:
    
    @interface Fraction: NSObject
    {
        int numerator; //定义实例变量
        int denominator; //定义实例变量
    }
    -(void) print; //定义了名称为print的,一个没有返回值的实例方法
    -(void) setNumerator:(int) n;
    -(void) setDenominator:(int) d;
    @end
    Fraction 是我们创建类的名称 Fraction: NSObject 表示Fraction继承了NSObject类。
    int numerator; 是定义一个实例变量,它的类型是“整数”
    -(void) setNumerator; 是定义一个实例方法,“-”号表示 “实例方法”,如果是“+”则表示类的方法,后面(int)n;表示这个方法用到的参数名称为n,它的类型为整型,void 表示这个方法没有返回值。
    
    那么什么是类的方法,什么又是实例的方法呢?
    
    用一个简单的例子,是最好的解释。假设我们有一个类的名字叫做 Car,我需要创建一个新的对象:myfirstcar,如何来做呢?
    myfirstcar = [Car creatCar];
    然后我需要为我的车加油,如何来做呢?
    [myfirstcar getOil]
    其中, creatCar 就是类方法, getOil就是实例方法。由此可见,类方法只能操作“类本身”,或者用来创建一个实例对象,而实例方法则是对实例进行相关的操作。
    
    类的描述部分结束了,我们需要对类描述的方法进行“代码填充”,如果只描述个名称而不给它实际的内容,很显然是没有任何意义的。
    
    @implementation Fraction
    -(void)print
    {
      NSLog(@"%i/%i",numerator, denominator);
    }
    -(void)setNumerator:(int)n
    {
      numerator = n;
    }
    -(void)setDenominator:(int)d
    {
     denominator = d;
    }
    @end
    看到这里大家基本应该明白了这个类的作用就是打印一个分数,比如 定义分子是1 分母是2 打印出来1/2
    没什么意义就是为了解释类的整个创建过程。
    
    我们先前描述的三个方法: print setNumerator setDenominator 在这里被详细的写出了内容代码。
    有点类似于函数的定义 
    @implementation 后面跟的是类名Fraction,可别写错了。
    
    截至到这里,一个完整的类就被定义出来了。那么我们如何使用它呢?
    
    #import <Foundation/Foundation.h>
        int main (int argc, char *argv[]) {
            NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
            Fraction *myFraction;
            myFraction = [Fraction alloc]; //分配存储空间
            myFraction = [myFraction init];  //初始化实例变量 myFraction
            [myFraction setNumerator:1]; //调用实例方法
            [myFraction setDominator:3];//调用实例方法
            [myFraction print]; //调用实例方法
            [myFraction release]; //释放存储空间
            [pool drain];
            return 0;
        }
    我们首先需要创建一个类的实例 myFraction,然后为myFraction 分配存储空间 myFraction = [Fraction alloc]; 然后初始化 myFraction (包括了实例变量的初始化,实例方法的初始化)myFraction = [myFraction init];
    
    然后我们就可以使用 setNumerator 和 setDominator 以及print 方法了。
    因为没有返回值,所以格式就是 [myFraction setNumerator:1]; 表示调用 myFraction 的 setNumerator 方法,setNumerator这个方法执行后将为 numerator 这个实例变量赋值 也就是说 numerator 的值被设定为 1 。
    
    为了将最后的结果打印出来,我们使用了[myFraction print]; 
    
    这就是一个类从创建到使用的完整过程

    OC 中基本类型定义 id, BOOL:

    在Objective-C 中,id 类型是一个独特的数据类型。在概念上,类似Java 的Object 类,可以转换为任何数据类型。换句话说,id 类型的变量可以存放任何数据类型的对象。在内部处理上,这种类型被定义为指向对象的指针,实际上是一个指向这种对象的实例变量的指针

    typedef signed char BOOL;
    
    #define YES      (BOOL) 1
    #define NO       (BOOL) 0
    

    4. 定义一个类字段:

    字段定义

    三种作用域:@public @protected(保护,在类本身或者子类中) @private (只能在类的内部)

    补充:缺省的是protected

    函数全部用public

    变量必须定义在类{}之间的地方

    注:在c中函数和字段是可以重名的

    #import <Foundation/Foundation.h>
    
    @interface Student : NSObject {
        int age; // 年龄
        
        @public
        int no; // 学号
        int score; // 成绩
        
        @protected
        float height; // 身高
        
        @private
        float weight; // 体重
    }
    
    @end
    

      

    用类的定义来创建一个实例,就叫做类的实例化。

    5.  类和实例的区别

    方法根据是否有static修饰也可以分为类方法和对象方法(实例方法)。
    访问时,类方法可以直接通过类名来引用,而实例方法必须通过对象名来访问,也就是说要想使用实例方法,就必须创建一个该类的对象。
    Math类的方法都是类方法,在使用时,可以如下:
    double s=Math.sin(30);
    Properties prop=System.getProperties();
    一般而言,类方法的执行不依对象而改变。在定义方法时,一些与对象无关的通用方法通常被定义为类方法。由于类方法是属于整个类的,并不属于哪个对象,所以类方法的方法体中不能有与类的对象有关的内容,所以出现下面的情况的时候会出现编译错误:
    1 类方法中不能引用对象变量
    2 类方法中不能调用类的对象方法
    3 在类方法中不能使用super、this关键字。
    使用对象方法时,必须先创建对象实例,然后才能使用,如:
    Student stu=new Student("0701956");
    stu.showAcademicRecord();
    与类方法相比,对象方法基本上没有什么限制:
    1 对象方法可以引用对象变量,也可以引用类变量
    2 对象方法中可以调用类方法
    3 对象方法中可以使用super、this关键字。
    

      

    Ps : 定义以及解释摘抄于IT网站上,搜集起来仅供参考。

  • 相关阅读:
    第六章 装饰模式
    第二章 策略模式
    第一章 简单工厂模式
    HTTPS-post请求
    import&export
    Flask(Jinja2) 服务端模板注入漏洞vulhub
    MySQL UDF提权 过程及注意事项
    centos7 安装jdk1.8.0_271 以及错误解决
    WEB、FTP服务器所有响应码解释(超详细)
    Wolf CMS后台文件上传getshell并提权
  • 原文地址:https://www.cnblogs.com/firstrate/p/3599277.html
Copyright © 2011-2022 走看看