(译)Getting Started——1.3.4 Writing a Custom Class(编写自定义的类)

  在开发IOS应用中,当你编写自定义的类时,你会发现很多的特殊场合。当你需要把自定义的行为和数据包装在一起时,自定义的类非常有用。在自定义的类中,你可以定义自己的存储、处理和显示数据的方法。

例如,IOS Clock应用中的World Clock面板。table view中的单元格需要显示比标准table view单元格更多的显示内容。这就是一个很好的机会来实现一个继承了UITableViewCell类的子类,用于在给定的table view单元格中显示更多的自定义内容。如果你正在设计自定义的类,你或许给某个label添加了outlet用于在信息前显示时间,还可以在单元格的右边,在自定义的时钟前显示图片等。

本节的主要内容就是让你知道Objective-C的语法和类的结构,这样就可以完成ToDoList应用的剩余行为了。从前面章节已经讨论过的ToDoItem的设计中可以知道,自定义的类在待办列表中扮演着单独的角色。在今天的教程里,你就会实现这个类并把它添加到应用中。

类的申明与实现

Objective-C中,一个类被分为两部分:接口和实现。接口中精确的定义了外部对象如何使用类中给定类型的对象。换句话说,接口定义了类实例与外部环境之间的接口。实现类中,包含了接口中申明的所有方法的可执行代码。

对象的设计思路是隐藏内部的实现细节。在Objective-C中,接口与实现通常被分开放置在单独的文件夹中,这样,你只需要让接口对外公开就可以了。使用C语言编程时,通过定义头文件和源文件的方法来把公共的申明与代码的实现细节分开。接口文件的后缀是.h,实现文件的后缀是.m。

接口

Objective-C中,接口申明的代码如下:

  

@interface ToDoItem : NSObject

@end

上面的代码中,申明了一个名为ToDoItem的类,它的父类是NSObject。

接口中,公用的属性和行为都定义在@interface申明中。上面的代码中,子类没有指定与父类不一样的东东,因此,ToDoItem的实例可以使用的行为全都继承自NSObject类。所有的对象都会有一个最小行为,因此,所有类都默认继承NSObject(或者NSObject的子类)。

实现

Objective-C语法中,类的实现如下所示:

#import "ToDoItem.h"

@implementation ToDoItem

@end

  如果你在接口中申明了方法,你需要在实现类中实现这些方法。

存储对象数据的属性

从待办列表项要存储的数据来分析,应该显示待办事项的名称,待办事项创建的时间,和待办事项计划完成的时间。因此,在自定义的ToDoItem类中,你需要在属性中存储这些信息。

在接口文件(ToDoItem.h)中,申明这些属性,如下所示:

  

@interface ToDoItem : NSObject

@property NSString *itemName;

@property BOOL completed;

@property NSDate *creationDate;

@end

在本例中,ToDoItem类申明了三个公共的属性。除非你再申明了其它的属性,否则,其它的对象只能对这三个属性的值进行读写。

要申明只读的属性,你需要在属性前再指定限定词。例如,如果你不想其它对象改变待办事项的创建时间,那你需要 这样做:

  

@interface ToDoItem : NSObject

@property NSString *itemName;

@property BOOL completed;

@property (readonly) NSDate *creationDate;

@end

属性可以是私有(private)的,也可以是公开(public)的。当把一个属性设置为私有类型时,其它的类就不能看到和获取它。例如,如果你想跟踪一个代表了项目日期的属性,又不想其它的类获取这个信息,那你可以在类实现(ToDoItem.m)文件的#import语句之后,在类的扩展里添加该属性,如下所示:

  

#import "ToDoItem.h"

@interface ToDoItem ()

@property NSDate *completionDate;

@end

@implementation ToDoItem

@end

使用getter和setter来获取属性。getter返回了属性的值,setter改变了属性的值。访问getter和setter的常见语法是点语法。对于要读写的属性来说,你可以使用点语法来对属性进行读写。如果你有一个对象:toDoItem,它是ToDoItem类的实例,那你可以这样做:

  

toDoItem.itemName = @"Buy milk";                 //Sets the value of itemName

NSString *selectedItemName = toDoItem.itemName;  //Gets the value of itemName

方法定义了对象的行为

方法定义了对象可以做什么。方法是在类中定义的,用于执行任务的代码片断。方法可以获取定义在类中的数据,也可以使用数据来执行某个操作。

例如,要想给待办事项添加被标记为完成状态的能力,你需要在接口中添加名为markAsCompleted的方法。然后,在实现类中实现这个方法的细节,如下所示:

  

@interface ToDoItem : NSObject

@property NSString *itemName;

@property BOOL completed;

@property (readonly) NSDate *creationDate;

- (void)markAsCompleted;

@end

方法前的-号表明了该方法是一个实例方法,由对象的实例调用,方法前面是一个+号的方法是类方法,类方法由类本身调用。类方法调用的常见例子是类的构造方法,你可以使用类方法获取与类相关的共享信息。

void关键字表示方法没有返回值。上面的代码中,markAsCompleted方法没有参数。

方法参数

在方法被调用时,方法里的参数会被当作方法信息的一部分被传递。

例如,你可以修改上面的代码,把markAsCompleted方法改为有一个参数的方法,这个参数用于决定某个待办事项到底是被标记为已完成还是未完成。这样,你就可以通过这个方法对待办事项设置完整的状态(完成和未完成),而不只是设置完成状态了。

  

@interface ToDoItem : NSObject

@property NSString *itemName;

@property BOOL completed;

@property (readonly) NSDate *creationDate;

- (void)markAsCompleted:(BOOL)isComplete;

@end

如上所示,已经给markAsCompleted方法添加了一个名为isComplete的参数,参数的类型是BOOL。

如果一个方法有多个参数,那么,方法名称就会被分成几个部分,每个部分都是参数的名称。如果你想给markAsComplete方法添加参数,那该方法的申明应该如下所示:

  

- (void)markAsCompleted:(BOOL)isComplete onDate:(NSDate *)date;

注意:上述代码中,方法的名称是markAsCompleted:onDate:。在实现过程中,当方法被调用时,isComplete和date这两个名字用于获取提供的值,就好像这两个名字就是变量一样。

实现方法

方法的实现是把相关的代码放在括号内。方法的名称、参数、返回类型必须与接口中定义的一样。

下面的代码是markAsCompleted:方法的实现:

  

@implementation ToDoItem

- (void)markAsCompleted:(BOOL)isComplete {

   self.completed = isComplete;

}

@end

与属性类似,方法的类型可以是private的,也可以是public的。申明在公共接口中的公共方法可以被其它对象看见和调用,其它对象看不到公共方法的具体实现。私有的方法只是在类的内部可见,也就是说私有的方法只能在类的内部被调用。这种机制非常强大,可以保证添加的类内部行为不会被其它对象调用。

例如,如果待办事项被标记为完成,那就给completionDate属性设置当前的日期。如果被标记为未完成,就把completionDate属性设置为nil。因为更新待办事项的completionDate属性是一个内部任务,因此,最佳的做法就是写类方法。但是,又得确保其它对象不能调用这个方法——否则,其它对象就可以在任意时间去改变待办事项的completionDate属性了。基于以上的考虑,应该把这个方法设置为private。

要完成上述内容,你需要更新ToDoItem的实现,在实现中添加私有的setCompletionDate方法,这个方法由类内部的markAsCompleted:方法调用,用于在待办事项被标记为完成或未完成时,更新待办项目的completionDate属性的值。注意:你并没有给接口文件添加任何东东,这是因为你不想让其它对象看到这个方法:

  

@implementation ToDoItem

- (void)markAsCompleted:(BOOL)isComplete {

   self.completed = isComplete;

   [self setCompletionDate];

}

- (void)setCompletionDate {

   if (self.completed) {

       self.completionDate = [NSDate date];

   } else {

       self.completionDate = nil;

   }

}

@end

到现在为止,你使用ToDoItem类已经设计了一个待办事项的基本表现形式。ToDoItem用属性的方式存储了待办事项本身的信息——名称,创建日期,完成状态,该类还定义了能做的行为——把待办事项标记为完成或未完成。现在,是时候把这个类添加到应用中了。

时间: 2025-01-08 17:06:36

(译)Getting Started——1.3.4 Writing a Custom Class(编写自定义的类)的相关文章

Writing Your Own Widget(自定义组件)

英文地址:http://dojotoolkit.org/reference-guide/1.10/quickstart/writingWidgets.html#quickstart-writingwidgets 从头单独开发一个控件十分困难,我们提供有一些组件,你如果想修改他们或者扩展一个自己的组件,这是毫无问题的. Dijit的组件具有可扩展性,修改组件时你没有必要熟读源代码.很多时候,你只需要通过设定组件的属性达到自己想要的目标,例如:滑块儿长度默认为0-100,你可以设定属性0-200达到

Ansible configure management--翻译(二)

一. Getting Started with Ansible Ansible is profoundly different from other configuration management tools available today. It has been designed to make configuration easy in almost every way, from its simple English configuration syntax to its ease o

[翻译]Writing Custom Common Controls 编写自定义控件

摘要:介绍如何编写自定义的控件,用在报表的窗体上(如Edit,Button等)   Writing Custom Common Controls 编写自定义控件 FastReport contains a set of common controls which can be placed on dialogue forms inside reports. They are as follows: FastReport包含以下控件,用于报表里的对话形式窗体. TfrxLabelControl T

八、Django之Models(译)

本文为翻译的官方文档,原文地址为:https://docs.djangoproject.com/en/1.11/topics/db/models/.学习工具的最佳地方-官网. model是唯一且明确的数据源.它包含了我们储存的数据的基本字段和方法.通常,每个模型映射到一张数据表. 基本概念: 每个模型都是django.db.models.Model的一个子类 每个属性代表数据库中的一个字段 在这些基础上,Django为我们提供了一个自动生成的数据库访问API. 简单示例 下面的示例模型定义了一个

舆情,文本挖掘

MLE,MAP,EM 和 point estimation 之间的关系是怎样的 和点估计相对应的是区间估计,这个一般入门的统计教材里都会讲.直观说,点估计一般就是要找概率密度曲线上值最大的那个点,区间估计则要寻找该曲线上满足某种条件的一个曲线段. 最大似然和最大后验是最常用的两种点估计方法.以最简单的扔硬币游戏为例,一枚硬币扔了五次,有一次是正面.用最大似然估计,就是以这五次结果为依据,判断这枚硬币每次落地时正面朝上的概率(期望值)是多少时,最有可能得到四次反面一次正面的结果.不难计算得到期望概

android官方技术文档翻译——Android Lint

本文译自androd官方技术文档<Android Lint>,原文地址:http://tools.android.com/tips/lint. 本文地址:http://blog.csdn.net/maosidiaoxian/article/details/41592783.转载请注明出处.翻译如有错讹,敬请指正. Android Lint Android Lint是在ADT 16(和 Tools 16)引入的一个新工具,可以扫描Android 项目源码中潜在的bug .它可同时作为一个命令行工

高质量C++/C编程指南

http://man.chinaunix.net/develop/c&c++/c/c.htm#_Toc520634042 文件状态 [  ] 草稿文件 [√] 正式文件 [  ] 更改正式文件 文件标识: 当前版本: 1.0 作    者: 林锐 博士 完成日期: 2001年7月24日 版 本 历 史 版本/状态 作者 参与者 起止日期 备注 V 0.9 草稿文件 林锐 2001-7-1至 2001-7-18 林锐起草 V 1.0 正式文件 林锐 2001-7-18至 2001-7-24 朱洪海

java字节码忍者禁术

Java语言本身是由Java语言规格说明(JLS)所定义的,而Java虚拟机的可执行字节码则是由一个完全独立的标准,即Java虚拟机规格说明(通常也被称为VMSpec)所定义的. JVM字节码是通过javac对Java源代码文件进行编译后生成的,生成的字节码与原本的Java语言存在着很大的不同.比方说,在Java语言中为人熟知的一些高级特性,在编译过程中会被移除,在字节码中完全不见踪影. 这方面最明显的一个例子莫过于Java中的各种循环关键字了(for.while等等),这些关键字在编译过程中会

(转)非常完善的Log4net详细说明

转自:http://www.cnblogs.com/zhangchenliang/p/4546352.htmlhttp://www.cnblogs.com/zhangchenliang/p/4546352.html (转)非常完善的Log4net详细说明 1.概述 log4net是.Net下一个非常优秀的开源日志记录组件.log4net记录日志的功能非常强大.它可以将日志分不同的等级,以不同的格式,输出到不同的媒介.本文主要是介绍如何在Visual Studio2008中使用log4net快速创