当前位置: 编程技术>移动开发
本页文章导读:
▪Object-C学习(3) Object-C学习(三)
引用:http://blog.csdn.net/huanglx1984/article/details/4296276我们接着来看objective c中面向对象的特性。要谈到面向对象,就不可能不说继承和多态。其实,我们之前就已经谈到了继.........
▪ TextView 中文字滚动的先决条件 TextView 中文字滚动的必要条件
在有多个控件中,TextView要让其文字能滚动的的必要条件如下:
android:singleLine="true"
android:ellipsize="marquee"
android:focusableInTouchMode="true"
android:focusable="true"
以上.........
▪ Object-C学习(4) Object-C学习(四)
引用:http://blog.csdn.net/huanglx1984/article/details/4299965我们之前说到Objective-C 是一种很好的面向对象的语言,和C++ 和Java 相比,Objective-C 有一些自己独特的东西,下面我们来.........
[1]Object-C学习(3)
来源: 互联网 发布时间: 2014-02-18
Object-C学习(三)
引用:http://blog.csdn.net/huanglx1984/article/details/4296276
我们接着来看objective c中面向对象的特性。要谈到面向对象,就不可能不说继承和多态。
其实,我们之前就已经谈到了继承,因为在objective c中,所有类都是从NSObject继承而来的。
继承,可以理解为“is-a”的关系,这个概念相信对大部分人来说都在熟悉不过了,关于C++和Java的任何一本书都会详细介绍这个概念,这里我不再赘述,直接上例子。
// Rectangle.h
#import <Foundation/NSObject.h>
@interface Rectangle:NSObject {
int width, height;
}
- (Rectangle*) initWithWidth:(int)w andHeight:(int)h;
- (void) setWidth: (int)w;
- (void) setHeight: (int)h;
- (void) setWidth: (int)w andHeight:(int)h;
- (int) width;
- (int) height;
- (void) print; // printf("width is %i, height is %i/n", [self width], [self height]);
@end
- (Rectangle*) initWithWidth:(int)w andHeight:(int)h 和- (void) setWidth: (int)w andHeight:(int)h 都是带多个参数的函数声明(参见第一篇)。
我们再实现一个正方形的类,继承矩形。
// Square.h
#import "Rectangle.h"
@interface Square:Rectangle {
}
- (Square*) initWithSize: (int)s;
- (void) setSize: (int)s;
- (int) size;
@end
// Square.m
@implementation Square
- (Square*) initWithSize: (int)s {
if( self = [super init] ) {
[self setSize:s];
}
return self;
}
- (void) setSize: (int)s {
width = s;
height = s;
}
- (int) size {
return width;
}
- (void) setWidth: (int)w {
[self setSize:w];
}
- (void) setHeight: (int)h {
[self setSize:h];
}
- (void) print {
printf( "the size is %i/n", [self size] );
}
@end
上面这个正方形类,继承了矩形类的成员变量。但是由于正方形的几何特殊性(长=宽),所以在正方形类中添加了三个方法。
分别是initWithSize,setSize,size 。另外,我们重载了矩形类中的setWidth 和setHeight 方法,因为正方形不允许分别设置长和宽。
如何使用:
int main( int argc, char* argv[] ) {
Rectangle* rect = [[Rectangle alloc] initWithWidth:10 andHeight:5];
Square* sq = [[Square alloc] initWithSize:10];
[rect print];
[sq print];
[rect release];
[sq release];
}
有了继承,我们就来说一说多态性。C++中虚函数的概念相信大家都不陌生,它通过一个虚拟表(virtual table)实现了动态绑定(dynamic binding)。
在objective c中也有类似的概念。
我们就以上面两个类为例子:
int main ( int argc, char* argv[] ) {
Rectangle *rect = [[Rectangle alloc] initWithWidth:10 andHeight:5];
Square *sq = [[Square alloc] initWithSize: 5];
id shape;
shape = rect;
[shape print]; // call the Rectangle's print
shape = sq;
[shape print]; // call the Square's print
... ...
}
这里,引入了objective c的一个很重要的关键词 id 。
我们可以将id理解为C++中的void*,所以我们能将rect和sq都赋值给shape。
那么shape是怎么知道调用哪个版本的print的呢?
还记得第一篇中我们提到的message的概念么?虽然id不知道如何响应print,但是它可以把这个消息传递给rect或者sq。
和c++与Java一样,objective c也支持run-time的类类型检查
- (BOOL) isKindOfClass: classObj
用于判断该对象是否属于某个类或者它的子类。
// true
如: if( [sq isKindOfClass: [Rectangle class]] == YES ) {}
- (BOOL) isMemberOfClass: classObj
用于判断该对象是否属于某个类(这里不包括子类)
// true
如: if( [sq isMemberOfClass: [Rectangle class]] == NO ) {}
- (BOOL) respondsToSelector: selector
用于判断该对象是否能响应某个消息。这里,我们可以将@selector后面带的参数理解为C++中的函数指针。
注意:1)不要忘了@ 2)@selector后面用的是(),而不是[]。3)要在消息名称后面跟:,无论这个消息是否带参数。
// true
如: if( [sq respondsToSelector: @selector(setSize:)] == YES ) {}
+ (BOOL) instancesRespondToSelector: selector
用于判断该类是否能响应某个消息。这是一个静态函数。
// true
如: if( [Square instancesRespondToSelector: @selector(setSize:)] == YES ) {}
引用:http://blog.csdn.net/huanglx1984/article/details/4296276
我们接着来看objective c中面向对象的特性。要谈到面向对象,就不可能不说继承和多态。
其实,我们之前就已经谈到了继承,因为在objective c中,所有类都是从NSObject继承而来的。
继承,可以理解为“is-a”的关系,这个概念相信对大部分人来说都在熟悉不过了,关于C++和Java的任何一本书都会详细介绍这个概念,这里我不再赘述,直接上例子。
// Rectangle.h
#import <Foundation/NSObject.h>
@interface Rectangle:NSObject {
int width, height;
}
- (Rectangle*) initWithWidth:(int)w andHeight:(int)h;
- (void) setWidth: (int)w;
- (void) setHeight: (int)h;
- (void) setWidth: (int)w andHeight:(int)h;
- (int) width;
- (int) height;
- (void) print; // printf("width is %i, height is %i/n", [self width], [self height]);
@end
- (Rectangle*) initWithWidth:(int)w andHeight:(int)h 和- (void) setWidth: (int)w andHeight:(int)h 都是带多个参数的函数声明(参见第一篇)。
我们再实现一个正方形的类,继承矩形。
// Square.h
#import "Rectangle.h"
@interface Square:Rectangle {
}
- (Square*) initWithSize: (int)s;
- (void) setSize: (int)s;
- (int) size;
@end
// Square.m
@implementation Square
- (Square*) initWithSize: (int)s {
if( self = [super init] ) {
[self setSize:s];
}
return self;
}
- (void) setSize: (int)s {
width = s;
height = s;
}
- (int) size {
return width;
}
- (void) setWidth: (int)w {
[self setSize:w];
}
- (void) setHeight: (int)h {
[self setSize:h];
}
- (void) print {
printf( "the size is %i/n", [self size] );
}
@end
上面这个正方形类,继承了矩形类的成员变量。但是由于正方形的几何特殊性(长=宽),所以在正方形类中添加了三个方法。
分别是initWithSize,setSize,size 。另外,我们重载了矩形类中的setWidth 和setHeight 方法,因为正方形不允许分别设置长和宽。
如何使用:
int main( int argc, char* argv[] ) {
Rectangle* rect = [[Rectangle alloc] initWithWidth:10 andHeight:5];
Square* sq = [[Square alloc] initWithSize:10];
[rect print];
[sq print];
[rect release];
[sq release];
}
有了继承,我们就来说一说多态性。C++中虚函数的概念相信大家都不陌生,它通过一个虚拟表(virtual table)实现了动态绑定(dynamic binding)。
在objective c中也有类似的概念。
我们就以上面两个类为例子:
int main ( int argc, char* argv[] ) {
Rectangle *rect = [[Rectangle alloc] initWithWidth:10 andHeight:5];
Square *sq = [[Square alloc] initWithSize: 5];
id shape;
shape = rect;
[shape print]; // call the Rectangle's print
shape = sq;
[shape print]; // call the Square's print
... ...
}
这里,引入了objective c的一个很重要的关键词 id 。
我们可以将id理解为C++中的void*,所以我们能将rect和sq都赋值给shape。
那么shape是怎么知道调用哪个版本的print的呢?
还记得第一篇中我们提到的message的概念么?虽然id不知道如何响应print,但是它可以把这个消息传递给rect或者sq。
和c++与Java一样,objective c也支持run-time的类类型检查
- (BOOL) isKindOfClass: classObj
用于判断该对象是否属于某个类或者它的子类。
// true
如: if( [sq isKindOfClass: [Rectangle class]] == YES ) {}
- (BOOL) isMemberOfClass: classObj
用于判断该对象是否属于某个类(这里不包括子类)
// true
如: if( [sq isMemberOfClass: [Rectangle class]] == NO ) {}
- (BOOL) respondsToSelector: selector
用于判断该对象是否能响应某个消息。这里,我们可以将@selector后面带的参数理解为C++中的函数指针。
注意:1)不要忘了@ 2)@selector后面用的是(),而不是[]。3)要在消息名称后面跟:,无论这个消息是否带参数。
// true
如: if( [sq respondsToSelector: @selector(setSize:)] == YES ) {}
+ (BOOL) instancesRespondToSelector: selector
用于判断该类是否能响应某个消息。这是一个静态函数。
// true
如: if( [Square instancesRespondToSelector: @selector(setSize:)] == YES ) {}
[2] TextView 中文字滚动的先决条件
来源: 互联网 发布时间: 2014-02-18
TextView 中文字滚动的必要条件
在有多个控件中,TextView要让其文字能滚动的的必要条件如下:
以上我试过,缺一不可。
然后再个是
可设置控件滚动的次数,如上表示滚动3次。
默认本以为是无限次,试了下,滚动几分钟还是停止了。
那要无限次最好加下属性:
在有多个控件中,TextView要让其文字能滚动的的必要条件如下:
android:singleLine="true" android:ellipsize="marquee" android:focusableInTouchMode="true" android:focusable="true"
以上我试过,缺一不可。
然后再个是
android:marqueeRepeatLimit="3"
可设置控件滚动的次数,如上表示滚动3次。
默认本以为是无限次,试了下,滚动几分钟还是停止了。
那要无限次最好加下属性:
android:marqueeRepeatLimit="marquee_forever"
[3] Object-C学习(4)
来源: 互联网 发布时间: 2014-02-18
Object-C学习(四)
引用:http://blog.csdn.net/huanglx1984/article/details/4299965
我们之前说到Objective-C 是一种很好的面向对象的语言,和C++ 和Java 相比,Objective-C 有一些自己独特的东西,下面我们来简单的介绍一下。
1)Category
回想一下,在C++ 中,如果我们想继承一个类,给它添加一些新的功能,我们需要什么?当然是我们需要得到这个类的源代码。但是在Objective-C 中,由于有了这个Category 的概念,我们可以在没有源代码的情况下,为一个已经存在的类添加一些新的功能,比如:
// DisplayMath.h
@interface Rectangle(Math)
- (int) calculateArea;
- (int) calculatePerimeter;
@end
// DisplayMath.m
@implementation Rectangle(Math)
- (int) calculateArea {
return width*height;
}
- (int) calculatePerimeter {
return 2*(width+height)
}
@end
这里,使用了之前定义的Rectangle 类,我们想为它添加两个功能:计算面积和周长。即使没有Rectangle 类的源代码,我们也可以通过Category 创建Rectangle 的子类。
使用Category的时候,需要注意两个地方:
1) 只能添加新的方法,不能添加新的数据成员
2)Category 的名字必须是唯一的,比如这里,就不允许有第二个Math 存在。
如何使用:
int main( int argc, char* argv[] ) {
Rectangle *rect = [[Rectangle alloc] initWithWidth: 5 andHeight:10];
[rect calculateArea];
[rect release];
}
2)如何创建私有方法
我们知道可以使用@private来声明私有变量,但是如何声明私有方法呢?
Objective-C 中并没有什么关键词来修饰方法,如果我们想让某个方法不被其他的类所见,唯一的方法就是不让这个方法出现在头文件中。比如:
// MyClass.h
#import <Foundation/NSObject.h>
@implementation MyClass
- (void) sayHello;
@end
// MyClass.m
#import "MyClass.h"
@implementation MyClass
- (void) sayHello {
NSLog(@"Hello");
}
@end
@interface MyClass(Private)
- (void) kissGoodbye;
@end
@implementation MyClass(Private)
- (void) kissGoodbye {
NSLog(@"kissgoodbye");
}
@end
怎么样,看到了Category 的应用么?是的,利用Category 可以方便的实现“私有”方法。
3)Protocol
在Objective-C 中,Protocol 的概念很象Java 中的interface 或者C++ 中的virtual class 。
来看下面这个例子:
@protocol Printing
- (void) print;
@end
// MyDate.h
@interface MyDate: NSObject <Printing> {
int year, month, day;
}
- (void) setDateWithYear: (int)y andMonth: (int)m andDay: (int)d;
@end
// MyDate.m
#import <stdio.h>
#import "MyDate.h"
@implementation MyDate
- (void) setDateWithYear: (int)y andMonth: (int)m andDay: (int)d {
year = y;
month = m;
day = d;
}
- (void) print {
printf( "%4d-%2d-%2d", year, month, day );
}
@end
我们首先声明了Printing 协议,任何遵守这个协议的类,都必须实现print 方法。在Objective C 中,我们通过<>来表示遵守某个协议。当某个类声明要遵守某个协议之后,它就必须在.m文件中实现这个协议中的所有方法。
如何使用:
int main( int argc, char* argv[] ) {
MyDate * dat = [[MyDate alloc] init];
[dat initDateWithYear:1998 andMonth:09 andDay:01];
id<Printing> var = dat;
[var print];
if( [dat conformsToProtocol:@protocol(Printing)] == YES ) {} // true
[dat release];
}
注意两个地方:1)使用id<Printing> 作为类型,而不是象C++中,使用Printing* var; 2)conformsToProtocol 类似于之前所说的respondsToSelector ,用于动态检查某个对象是否遵守某个协议。
引用:http://blog.csdn.net/huanglx1984/article/details/4299965
我们之前说到Objective-C 是一种很好的面向对象的语言,和C++ 和Java 相比,Objective-C 有一些自己独特的东西,下面我们来简单的介绍一下。
1)Category
回想一下,在C++ 中,如果我们想继承一个类,给它添加一些新的功能,我们需要什么?当然是我们需要得到这个类的源代码。但是在Objective-C 中,由于有了这个Category 的概念,我们可以在没有源代码的情况下,为一个已经存在的类添加一些新的功能,比如:
// DisplayMath.h
@interface Rectangle(Math)
- (int) calculateArea;
- (int) calculatePerimeter;
@end
// DisplayMath.m
@implementation Rectangle(Math)
- (int) calculateArea {
return width*height;
}
- (int) calculatePerimeter {
return 2*(width+height)
}
@end
这里,使用了之前定义的Rectangle 类,我们想为它添加两个功能:计算面积和周长。即使没有Rectangle 类的源代码,我们也可以通过Category 创建Rectangle 的子类。
使用Category的时候,需要注意两个地方:
1) 只能添加新的方法,不能添加新的数据成员
2)Category 的名字必须是唯一的,比如这里,就不允许有第二个Math 存在。
如何使用:
int main( int argc, char* argv[] ) {
Rectangle *rect = [[Rectangle alloc] initWithWidth: 5 andHeight:10];
[rect calculateArea];
[rect release];
}
2)如何创建私有方法
我们知道可以使用@private来声明私有变量,但是如何声明私有方法呢?
Objective-C 中并没有什么关键词来修饰方法,如果我们想让某个方法不被其他的类所见,唯一的方法就是不让这个方法出现在头文件中。比如:
// MyClass.h
#import <Foundation/NSObject.h>
@implementation MyClass
- (void) sayHello;
@end
// MyClass.m
#import "MyClass.h"
@implementation MyClass
- (void) sayHello {
NSLog(@"Hello");
}
@end
@interface MyClass(Private)
- (void) kissGoodbye;
@end
@implementation MyClass(Private)
- (void) kissGoodbye {
NSLog(@"kissgoodbye");
}
@end
怎么样,看到了Category 的应用么?是的,利用Category 可以方便的实现“私有”方法。
3)Protocol
在Objective-C 中,Protocol 的概念很象Java 中的interface 或者C++ 中的virtual class 。
来看下面这个例子:
@protocol Printing
- (void) print;
@end
// MyDate.h
@interface MyDate: NSObject <Printing> {
int year, month, day;
}
- (void) setDateWithYear: (int)y andMonth: (int)m andDay: (int)d;
@end
// MyDate.m
#import <stdio.h>
#import "MyDate.h"
@implementation MyDate
- (void) setDateWithYear: (int)y andMonth: (int)m andDay: (int)d {
year = y;
month = m;
day = d;
}
- (void) print {
printf( "%4d-%2d-%2d", year, month, day );
}
@end
我们首先声明了Printing 协议,任何遵守这个协议的类,都必须实现print 方法。在Objective C 中,我们通过<>来表示遵守某个协议。当某个类声明要遵守某个协议之后,它就必须在.m文件中实现这个协议中的所有方法。
如何使用:
int main( int argc, char* argv[] ) {
MyDate * dat = [[MyDate alloc] init];
[dat initDateWithYear:1998 andMonth:09 andDay:01];
id<Printing> var = dat;
[var print];
if( [dat conformsToProtocol:@protocol(Printing)] == YES ) {} // true
[dat release];
}
注意两个地方:1)使用id<Printing> 作为类型,而不是象C++中,使用Printing* var; 2)conformsToProtocol 类似于之前所说的respondsToSelector ,用于动态检查某个对象是否遵守某个协议。
最新技术文章: