基于Objectvie-C基础教程(第2版)做的笔记

基于Objectvie-C基础教程(第2版)做的笔记

第一个Objective-C 程序:

main.m:

#import <Foundation/Foundation.h>

int main(int argc, const char *argv[])

{

NSLog(@"Hello, Objective-C");

return(0);

}//main

#import语句:与c语言一样,Objective-C使用头文件来包含结构体/符号变量和函数原型等元素的声明。

#import是由XCode使用编译器提供的, #import可保证头文件只被包含一次, 无论此命令在该文件出现了多少次。

程序中的#import <Foundation/Foundation.h>语句告诉编译器查找Foundation框架中的Foundation.h头文件。

框架:是一种把头文件/库/图片/声音等内容聚集在一个独立单元中的集合体。一般的框架集有:Cocoa/Carbon/QuickTime/OpenGL。

(Cocoa的组成部分有Foundation和Application Kit也称AppKit)框架。

Foundation框架处理的是用户界面之下的那些层(Layer)的特性。比如数据结构和通信机制。

每 个框架都是一个重要的技术集合,通常包含数十个甚至上百个头文件。每个框架都有一个主头文件, 它包含了框架内所有的头文件。通过在主头文件中使用#import, 就可以访问框架内的所有功能。(在Headers目录:/System/Library/Frameworks/Foundaton.framework /Headers/可以看到Foundation框架包含了哪些头文件)

NSLog() 和 @“字符串”:

NSLog函数:

NSLog (@ "Hello, Objective-C!");

此 代码可向控制输入Hello Objective-C!. NSLog()这个函数的作用和C语言中的printf()很相似。与printf()一样,NSLog()接受一个字符串作为其第一个参数,该字符串可 以包含格式说明符(比如%d),此函数会接受与格式说明符相符相匹配的其他参数。(由于Objective-C只是添加了一些新特性的C语言,所以可以用 printf()来代替NSLog())

NS前缀避免名称冲突。

Cocoa给其所有函数、常量和类型名称都添加了NS前缀。这个前缀告诉我们函数来自Cocoa而不是其他工具包。

Cocoa已占用了NS前缀,所以很明显你不能再给你的任何变量和函数名称添加前缀NS, 否则会让阅读代码的人产生混淆,会以为创建的内容实际上是属于Cocoa的。

NSLog (@ "Hello, Objective-C!");

@符号是Objective-C在标准C语言基础上添加的特性之一。意味着引号内的字符串应作为Cocoa的NSString元素来处理。

NSString:是Cocoa中的字符串。

NSArray存放数组、NSDateFormatter帮助你用不同的方式来设置时间格式、NSThread提供多线程编程工具。NSSpeechSynthesizer能够让你听到语音。

布尔类型:

Objective-C提供的布尔类型是BOOL,它具有YES和NO两个值。C语言的bool类型和Objective-C语言的BOOL类型可以在同一个程序中共存,但是如果编写的是Cocoa代码,就只能使用BOOL。

项目的创建步骤:

main.m文件:

#import <Foundation/Foundation.h>

// return NO if the two integers have the sam value, Yes otherwise.

BOOL areIntsDifferent (int thing1, int thing2)

{

if (thing1 == thing2) {

return(NO);

} else {

return (YES);

}

} // areIntsDifferent given a NO value, return the human-readable

// string "NO". Otherwise return "YES"

// 这里返回的值只能是BOOL类型的值:YES(1)或NO(0)

NSString *boolString (BOOL yesNo)

{

if (yesNo == NO) {

return (@"NO");

} esle {

return(@"YES");// 由于函数的返回类型是NSString类型,所以加上@“”,以表示返回的是字符串。

}

}// boolString

int main(int argc, const char *argv[])

{

BOOL areTheyDifferent;// 声明一个BOOL的值。

areTheyDifferent = areIntsDifferent (5, 5);

NSLog(@"are %d and %d different? %@", 5, 5, boolString(areTheyDifferent));

// 这里的两个5将替代两个%d的占位符。

// 在NSLog()的字符串的末尾,可以看到另一个@符号,这次表现为%@,它表示boolString()返回的是一个NSString指针。printf()不支持

// 输出NSString,所以没有能够使用的格式说明符。NSLog()的编写者添加%@格式的说明符,是为了通知NSLog()接受适当的参数,将其

// 作为NSString, 并使用该字符串中的字符,将其发送到控制台中。

areTheyDifferent  = areIntsDifferent (23, 42);

NSLog (@"are %d and %d different? %@", 23, 42, boolString(areTheyDifferent));

return(0);

}

面向对象(Object-Oriented Programming)即OOP,是一种编程架构, 可构建由多个对象组成的软件。对象就好比存在于计算机中的小零件,它们通过互相传递信息来完成工作。

OOP的一个关键概念:间接(indirection),间接这个词看似隐晦,其实意思非常简单--在代码中通过指针间接获取某个值。

变量与间接:基本变量就是间接的一种实际使用。

Code:

#import <Foundation/Foundation.h>

int main(int argv, const char *argv[])

{

NSLog(@"The numbers from 1 to 5: ");

for (int i = 1; i <= 5; i++) {

NSLog(@"%d\n", i);

}

return (0);

}

从上面的code可以看出,如果想要打印1到10, 就得更改NSLog函数里的字符串描述和for循环里的5改成10,但是如果当程序的代码量大的时候如果要修改,那么就会很麻烦,而变量就是用来解决此类问题的。

Code:

#import <Foundation/Foundation.h>

int main(int argv, const char *argv[])

{

int count = 5;

NSLog(@"The numbers from 1 to %d: ", count );

for (int i = 1; i <= count ; i++) {

NSLog(@"%d\n", i);

}

return (0);

}

使用文件名的间接,文件是间接的另一个示例。

Code:

#import <Foundation/Foundation.h>

int main(int argv, const char *argv[])

{

const char *word[4] = { "aardvark",  "abacus", "allude", "zygote" };

int wordCount = 4;

for (int i = 0; i < wordCount; i++) {

NSLog(@"%s is %lu characters long", words[i], strlen(words[i]));

// 使用%s是因为words是C字符串数组,而不是@“NSString”对象的数组。

// %lu格式说明符取计算字符串长度的strlen()函数的整数值,并输出单词及其长度。

}

return (0);

}

在上面的程序中,word数组的编辑需要注意标点符号,比如字母间的引号和输入项之间的逗号。如:

构建此程序的另一种方法就是将所有名字都移到代码之外的某个文件中,每行一个名字。没错,这就是间接。无需将名字直接放入源代码,而是让程序在其他地方查找这些名字。

Code:

#import <Foundation/Foundation.h>

int main(int argv, const char *argv[])

{

FILE *wordFile = fopen ("/tmp/words.txt", "r");

// fopen()函数打开word.txt文件以便读取内容, 然后

char word[100];

while (fgets(word, 100, wordFile))

// fgets()从文件中读取一行文本并将其放入字符数组word中。fgets()调用

// 会保留每行之间用来断行的换行符,如果留下它,换行符就会被计为单词中的一个字符。

// 所以我们把换行符替换为\0,这表示字符串的结束。

{

// strip off the trailing \n

word[strlen(word) - 1] = ‘\0‘;

NSLog(@"%s is %lu characters long", word, strlen(word));

}

fclose (wordFile);

return (0);

}

再次修改程序,不再通过/tmp/word.txt路径获取单词,修改程序, 使其查看程序的第一个启动参数,以确定单词文件的位置。

Code:

#import <Foundation/Foundation.h>

int main(int argc, const char *argv[])

{

if (argc == 1) {// 如果用户提供路径,argc会大于1.

NSLog(@"you need to provide a file name");

return (1);

}

FILE *wordFile = fopen(argv[1], "r");//argv[0]是程序名。

char word[100];

while (fgets(word, 100, wordFile)) //这里的100是指截取一行里的100个字符,如果一行的字符不满100,就取这一行的所有字符。

{

// strip off the trailing \n

word[strlen(word) - 1] = ‘\0‘;

NSLog(@"%s is %lu characters long", word, strlen(word));

}

fclose(wordFile);

return(0);

}

过程式编程(Procedual Programming)

Code:

#import <Foundation/Foundation.h>
// constants for the different kinds of shapes and their colors

typedef enum {
     kCircle,
     kRectangle,
     kOblateSpheroid
} ShapeType;

typedef enum {
     kRedColor,
     kGreenColor,
     kBlueColor
} ShapeColor;

// --------------------------------------------------
// Shape bounding rectangle

typedef struct {
     int x, y, width, height;
} ShapeRect;

// --------------------------------------------------
// The Shape

typedef struct {
     ShapeType type;
     ShapeColor fillColor;
     ShapeRect bounds;
} Shape;

// --------------------------------------------------
// convert from the ShapeColor enum value to a human-readable name

NSString *colorName (ShapeColor colorName)
{
    switch (colorName) {
        case kRedColor:
            return @"red";
            break;
        case kGreenColor:
            return @"green";
            break;
        case kBlueColor:
            return @"blue";
            break;
    }
   
    return @"no clue";
   
} // colorName

void drawCircle (ShapeRect bounds, ShapeColor fillColor)
{
     NSLog (@"drawing a circle at (%d %d %d %d) in %@",
             bounds.x, bounds.y,
             bounds.width, bounds.height,
             colorName(fillColor));
    
} // drawCircle

void drawRectangle (ShapeRect bounds, ShapeColor fillColor)
{
     NSLog (@"drawing a rectangle at (%d %d %d %d) in %@",
             bounds.x, bounds.y,
             bounds.width, bounds.height,
             colorName(fillColor));
    
} // drawRectangle

void drawEgg (ShapeRect bounds, ShapeColor fillColor)
{
     NSLog (@"drawing an egg at (%d %d %d %d) in %@",
             bounds.x, bounds.y,
             bounds.width, bounds.height,
             colorName(fillColor));
    
} // drawEgg

// --------------------------------------------------
// Draw the shapes

void drawShapes (Shape shapes[], int count)
{
     for (int i = 0; i < count; i++) {
         
          switch (shapes[i].type) {
                   
               case kCircle:
                    drawCircle (shapes[i].bounds,
                                   shapes[i].fillColor);
                    break;
                   
               case kRectangle:
                    drawRectangle (shapes[i].bounds,
                                      shapes[i].fillColor);
                    break;
                   
               case kOblateSpheroid:
                    drawEgg (shapes[i].bounds,
                              shapes[i].fillColor);
                    break;
          }
     }
    
} // drawShapes

// --------------------------------------------------
// The main function.  Make the shapes and draw them

int main (int argc, const char * argv[])
{
     Shape shapes[3];
    
     ShapeRect rect0 = { 0, 0, 10, 30 };
     shapes[0].type = kCircle;
     shapes[0].fillColor = kRedColor;
     shapes[0].bounds = rect0;
    
     ShapeRect rect1 = { 30, 40, 50, 60 };
     shapes[1].type = kRectangle;
     shapes[1].fillColor = kGreenColor;
     shapes[1].bounds = rect1;
    
     ShapeRect rect2 = { 15, 18, 37, 29 };
     shapes[2].type = kOblateSpheroid;
     shapes[2].fillColor = kBlueColor;
     shapes[2].bounds = rect2;
    
     drawShapes (shapes, 3);
    
     return (0);
    
} // main

上面的程序是使用过程式编程,但是编写这种代码必须注意要为各种数据类型使用正确的函数,并且程序的扩展和维护变得困难。

如果上面的代码要添加一个三角形的支持,那么要在4个地方进行添加。这还是程序小的时候,如果程序越复杂,扩展起来就越麻烦。

实现面向对象编程

过程式编程建立在函数之上, 数据为函数服务, 而面向对象编程则以程序的数据为中心, 函数为数据服务。在OOP中,不再重点关注程序的函数, 而是专注于数据。

用面向编程的思想来编写上面的程序:

这个时候在程序中的drawShapes方法是这样写的:

// Draw the shapes

void drawShapes (id shapes[], int count)
{
     for (int i = 0; i < count; i++) {
          id shape = shapes[i];
          [shape draw];
     }
    
} // drawShapes

该函数包含一个循环,用于遍历数组中的每个形状。在循环过程中,程序通知形状对象绘制自身。

有两个不同点,一是代码简洁了很多。另一个是函数的第一个参数shapes[],此时它是一个id数组对象。

id表示的是标识符(identifier)。 是一种泛型,可以用来引用任何类型的对象。对象是一种包含代码的struct结构体, 因此id实际上是一个指向结构体的指针。

id shape = shapes[i];--这一行代码从shapes数组获取id(即指向某个对象的指针),并将其赋值给类型为id名为shape的变量。是一种指针的赋值过程。

[shape draw];--在C语言中方括号是指数组,但是在Objective-C还有其他意义:用于通知某个对象该去做什么。方括号里的第一项是对象,其余部分是需要对象执行的操作。

在Objective-C中,通知对象执行某种操作称为发送消息(也称”调用方法“)。代码[shape draw]表示向shape对象发送了draw消息。向对象发送消息后,如何调用所需的代码,这就需要叫做类的幕后帮手来协助完成。

circle对象含有一个指向其类的指针。类是一种能够实例化成对象的结构体。Circle类含有一个指针指向用于绘制圆形、计算圆形的面积以及实现其他与圆形相关的必要功能的代码。如果在运行时改变某个类,则该类的所有对象会自动继承这些变化。

Objective-C语言中的OOP

@interface部分:

创建某个特定类的对象之前,Objective-C编译器需要一些有关该类的信息,尤其是对象的数据成员(即对象的C语言类型结构体应该是什么样子)及其提供的功能。可以使用@interface指令把这些信息传递给编译器。

Circle类的接口:

@interface Circle :NSObject

{

@private

ShapeColor fillColor;

ShapeRect bounds;

}

- (void) setFillColor : (ShapeColor) fillColor;

- (void) setBounds: (ShapeRect) bounds;

- (void) draw;

@end // Circle

Code分析:

@interface Circle : NSObject -- 在Objective-C中只要看到@符号,就可以把它看成是对C语言的扩展。@interface Circle告诉编译器:“这是新类Circle的接口”。

@interface行中的NSObject告诉编译器,Circle类是基于NSObject类的。该语句表明每个Circle类都是一个NSObject, 并且每个Circle类都将继承NSObject类定义的所有行为。

{

ShapeColor fillColor;

ShapeRect bounds;

}

花括号中的内容是用于大量创新Circle对象的模板。它表示创建的新对象由两个元素构成。

在类声明中指定fillColor和bounds后,每次创建Circle对象,对象中都将包括这两个元素。fillColor和bounds的值称为Circle类的实例变量(instance variable)

- (void) draw;

- (void) setFillColor: (ShapeColor) fillColor;

- (void) setBounds: (ShapeRect) bounds;

在Objective-C中,它们称为方法声明(method declaration)。方法声明列出了每个方法的名称、方法返回值的类型和某些参数。

声明前面的短线表明这个是Objective-C方法的声明。这个是区分函数原型与方法声明的一种方式,函数原型中没有先行短线。

短线后是方法的返回类型,位于圆括号中。void 表示无返回值。Objective-C方法可以返回与C函数相同的类型:标准类型(整型、浮点型和字符串)、指针、引用对象和结构体。

- (void) setFillColor: (ShapeColor) fillColor;在这个方法声明里, 这个方法还有一个参数fillColor。

声明以常见的先行短线和位于圆括号中的返回值类型开头:- (void)

方法名称是setFillColor:,结尾处的冒号是名称的一部分,它告诉编译器后编程人员后面出现参数。

(ShapeColor) fillColor;--参数类型是在圆括号中指定的。fillColor是参数名。

最后一行代码:@end告诉编译器,我们已经完成了Circle类的声明。

@implementation部分

上面的@interface部分,它用于定义类的公共接口。通常接口被称为API(application programming interface)。而真正使对象能够运行的代码位于@implementation部分中。

Circle类实现:

@implementation Circle

- (void) setFillColor: (ShapeColor) c

{

fillColor = c;

}// setFillColor

-(void) setBounds: (ShapeRect) b

{

bounds = b;

}// setBounds

Code分析:

@implementation Circle -- @implementation是一个编译器指令,表明你将为某个类提供代码。类名出现在@implementation之后。该行的结尾没有分号,因为在Objective-C编译器指令后不必使用分号。

接下来是各个方法的定义。它们不必按照在@interface指令中顺序出现。甚至可以在@implementation中定义那些在@interface中没有声明过的方法。可以把它们看作是仅能在当前类实现中使用的私有方法。

定义第一个方法:setFillColor:

- (void) setFillColor: (ShapeColor) c

{

fillColor = c;

}

与@interface部分的声明非常类似。主要区别是结尾处有没有分号。

在@implementation中,我们把参数重新命名为简单的字符c了。@interface和@implementation间的参数名不同是允许的。如果继续使用fillColor,就会覆盖fillColor实例变量,并且编译器会生成警告信息。

在@interface部分的方法声明中使用名称fillColor,是为了告诉读者参数的真正作用。在实现中,我们必须区分参数名称和实例变量的名称。


Objective-C中调用方法时,一个名为self的秘密隐藏参数将被传递给接收对象,而这个参数引用的就是该接收对象,也就是说self是类的隐藏
的参数,指向当前调用方法的类。例如,在代码[circle setFillColor: kRedColor]中,
方法将circle作为其self参数进行传递。因为self的传递过程是秘密和自动的,所以不用程序员去实现。方法中引用实例变量的代码与下面的相似:
self -> fillColor = c;

传递隐藏的参数是间接操作的有一个示例,因为Objective-C运行时(runtime)可以将不同的对象当成隐藏的self参数传递,所以那些对象的实例变量发生更改时,运行时也可以进行相应的更改。

最后一个方法draw,方法名结尾处没有冒号,说明它不适用任何参数。

- (void) draw

{

NSLog(@"drawing a circle at (%d %d %d %d) in %@", bounds.x, bounds.y, bounds.width, bounds.height, colorName(fillColor));

}

实例化对象:

实例化(instantiation).实例化对象时,需要分配内存,然后将这些内存初始化并保存为有用的默认值。这些值不同于通过新分配的内存获得的随机值。内存分配和初始化工作完成之后,就意味着新的对象实例已经创建好了。

以下是main()函数,它用于创建圆形,矩形,椭圆形

int main(int argc, const char *argv[])

{

id shapes[3],

ShapeRect rect0 = {0, 0, 10, 30};

shapes[0] = [Circle new];// new一个类对象。

[shapes[0] setBounds: rect0];// 执行对象的方法

[shapes[0] setFillColor: kRedColor];

ShapeRect rect1 = {30, 40, 50, 60};

shapes[1] = [Rectangle new];

[shapes[1] setBounds: rect1];

[shapes[1] setFillColor: kGreenColor];

ShapeRect rect2 = {15, 19, 37, 29};

shapes[2] = [Egg new];

[shapes[2] setBounds: rect2];

[shapes[2] setFillColor: kBlueColor];

drawShapes(shapes, 3);

return (0);

}

这个时候如果想要添加一个新的三角形类,就比较简单了,仅需要完成两件事:创建Triangle类,然后将Triangle对象添加到将要绘制的对象列表中。


面的代码正好验证了面向对象编程大师Bertrand Meyer的开放/关闭原则(Open/Closed
Principle),即软件实体应该对扩展开放,而对修改关闭。drawShapes()函数对扩展是开发的。仅需向数组添加要绘制的某个新型状。同
时,drawShapes()也是对修改关闭的,我们可以扩展它,而不必修改它。

继承:

处理类和对象的关系时,尤其要重视OOP的两个方面。第一个方面是继承(inheritance).使用继承可以定义一个具有父类所有功能的新类,即它继承了父类的功能。

另一个和类相关的OOP技术是复合(composition),也就是在对象中可以再引用其他对象。

OOP中的继承表明一个类从另一个类--它的父类或超类(superclass)--中获取了某些特性。

继承的语法格式

@interface Circle: NSObject--冒号后面的标识符是需要继承的类。

在Objective-C中,你可以选择不继承,但如果使用的是Cocoa框架,就需要继承NSObject类,因为它提供了大量有用的特性。(当继承一个继承自NSObject类的类时,也可以获取这些特性)

只能继承一个:某些编程语言(例如C++)具有多继承性,也就是一个类可以直接从两个或多个类继承而来。但Objective-C不支持多继承。

@interface Circle :NSObject, PrintableObject 这样是编译不过的。

当然可以通过Objective-C的其他特性来达到多继承的效果。例如类别(category)和协议(protocol)。

根据继承,修改上面的代码:

Circle和Rectangle的接口代码更改为:

@interface Circle :Shape

@end // Circle

@interface Rectangle : Shape

@end // Rectangle

--程序中没有声明实例变量时可以省略花括号。

Shape类的接口声明代码:

@interface Shape : NSObject {

ShapeColor fillColor;

ShapeRect bounds;

}

-(void) setFillColor:(ShapeColor) fillColor;

-(void) setBounds: (ShapeRect)bounds;

-(void) draw;

@end // Shape

Shape类的实现代码:

@implementation Shape

-(void) setFillColor: (ShapeColor) c

{

fillColor = c;

}// setFillColor

-(void)setBounds:(ShapeRect)b

{

bounds = b;

} // setBounds

-(void) draw

{

}// draw

@end // Shape

--虽然draw方法没有实现任何功能,但仍然需要定义它,以便Shape的所有子类都能通过它来实现各自的方法。

在方法的定义中不写任何内容或返回一个虚(dummy)值都是可以通过编译的。

Circle类的实现:

@implementation Circle

-(void) draw

{

NSLog(@"drawing a circle at (%d %d %d %d) in %@", bounds.x, bounds.y, bounds.width, bounds.height, colorName(fillColor));

} // draw

@end // Circle

Rectangle类的实现

@implementation Rectangle

-(void) draw

{

NSLog(@"drawing a rect at (%d %d %d %d) in %@", bounds.x, bounds.y, bounds.width, bounds.height, colorName(fillColor));

} // draw

@end // Rectangle

继承的工作机制

方法调度:

对象在收到消息时,如何知道要执行哪个方法?-- 当代码发送消息时,Objective-C的方法调度机制将在当前的类中搜索相应的方法,如果无法在接受消息的对象的类文件中找到相应的方法,它就会在该对象的超类中进行查找。


有引入Shape父类的程序中,对于类似[shape setFillColor: kRedColor]的代码,Objective-C
的方法调度机制首先会寻找接受消息的对象,在本例中的Circle对象拥有一个指向Circle类的指针,Circle类也有一个指向其相应代码的指针。
调度程序通过这些指针来查找正确的代码。

增加了继承的新架构:


向Circle类的对象发送setFillColor:消息时,调度程序首先询问Circle类中的代码能否响应setFillColor:消息,不能的
话,调度程序会溯流而上进入Shape类中,找到setFillColor:定义,之后运行这段代码。如果在最顶层的NSObject类中也没有找到该方
法,则会出现一个运行时错误,同时还会出现一个编译时(compile-time)警告信息。

实例变量

为了理解实例变量的继承机制,创建一个新的形状,接口代码如下:

@interface RoundedRectangle  : Shape

{

@private

int radius;

}

@end // RoundedRectangle

RoundedRectangle对象的内存布局。NSObject类声明了一个名为isa的实例变量,该变量保存了一个指向对象当前类的指针。

记住,每个方法调用都获得了一个名为self的隐藏参数,它是一个指向接收消息的对象的指针。这些方法通过self参数来寻找它们需要用到的实例变量。

重写方法

当父类提供了一个方法但让该方法的实现内容为空,这个每个子类都能实现各自的功能,当子类实现各自的方法时,就说它们重写了父类的方法。

super关键字

Objective-C提供了一种方法,既可以重写方法的实现,又能调用超类中的实现方式。为了调用继承的方法在父类中的实现,需要使用super作为方法调度的目标。

绘制的圆都是绿色的:

Circle类的@interface部分不需要修改,只需向@implementation部分添加以下代码:
@implementation Circle

-(void) setFillColor:(ShapeColor) c

{

if (c == kRedColor)

{

c = kGreenColor;

}

[super setFillColor: c];

}// setFillColor

@end // Circle

在这个新的setFillColor:实现中,我们会检查ShapeColor类型的参数是否是红色,如果是,就将它改成绿色,然后请求超类响应消息[super setFillColor:c]并将该颜色放入实例变量中。

super
既不是参数也不是实例变量,而是由Objective-C编译器提供的一种神奇的功能。当向super发送消息时,实际上是在请求Objective-C
向该类的超类发送消息。如果超类中没有定义该消息,Objective-c会和平常一样继续在继承链上一级查找。

时间: 11-28

基于Objectvie-C基础教程(第2版)做的笔记的相关文章

HTML5和CSS3基础教程(第8版)-读书笔记(2)

第7章 CSS构造模块 7.1 构造样式规则 样式表中包含了定义网页外观的规则.样式表中的每条规则都有两个主要部分:选 择 器(selector) 和 声 明 块(declaration block). 选择器决定哪些元素受到影响:声明块由一个或多个属性 - 值对(每个属性 -值对构成一条声明,declaration)组成,它们指定应该做什么. 声明块内的每条声明都是一个由冒号隔开.以分号结尾的属性- 值对. 声明的顺序并不重要,除非对相同的属性定义了两次. 在样式规则中可以添加额外的空格.制表

《jQuery基础教程(第四版)》学习笔记

第2章 选择元素 1. 使用$()函数 $()函数其实是创建了一个jQuery对象. 这个函数接受CSS选择符作为参数,充当一个工厂, 返回包含页面中对应元素的jQuery对象. 所有能在样式表中使用的选择符都可以传给这个函数, 随后就可以对匹配的元素集合应用jQuery方法. 在jQuery中,美元符号$其实就是标示符jQuery的"别名". 2. 选择符 1. 基本选择符 $('p') //取得所有标签为p的元素 $('.class') //取得所有类为class的元素 $('#i

《python基础教程第三版》高清版PDF免费下载

Python基础教程 第3版Python简明教程书籍 Python编程从入门到实践 灵程序设计丛书 下载地址:网盘下载 编辑推荐 久负盛名的Python入门经典 中文版累计销量200 000+册 针对Python 3全新升级 本书是经典的Python入门教程,层次鲜明.结构严谨.内容翔实,特别是后面几章,作者将前面讲述的内容应用到10个引人入胜的项目中,并以模板的形式介绍了项目的开发过程,手把手教授Python编程实践,让读者从项目中领略Python的真正魅力. 本书既适合初学者夯实基础,又能帮

《python基础教程(第二版)》学习笔记 字符串(第3章)

<python基础教程(第二版)>学习笔记 字符串(第3章)所有的基本的序列操作(索引,分片,乘法,判断成员资格,求长度,求最大最小值)对字符串也适用.字符串是不可以改变的:%左侧是格式字符串,右侧是需要格式化的值print '%s=%d' % ('x',100) ==> x=100%% 格式字符串中出现 %模板字符串:from string import Templates=Template('$x is 100');  s.substitute(x='ABC');  ==> '

《Python基础教程(第二版)》学习笔记 -&gt; 第九章 魔法方法、属性和迭代器

准备工作 >>> class NewStyle(object): more_code_here >>> class OldStyle: more_code_here 在这两个类中,NewStyle是新式的类,OldStyle是旧式的类,如果文件以__metaclass__ = type 开始,那么两个类都是新式类. 构造方法 构造方法,当一个对象被创建后,会立即调用构造方法.Python中创建一个构造方法,只要把init方法的名字从简单的init修改成__init__

《Python基础教程(第二版)》学习笔记 -&gt; 第十章 充电时刻 之 标准库

SYS sys这个模块让你能够访问与Python解释器联系紧密的变量和函数,下面是一些sys模块中重要的函数和变量: 函数和变量 描述 argv 命令行参数,包括脚本和名称 exit([arg])                退出当前的程序,可选参数为给定的返回值或者错误信息 modules 映射模块名字到载入模块的字典 path 查找模块所在目录的目录名列表 platform 平台标识符 stdin 标准输入流-- 一个类文件对象 stdout 标准输出流-- 一个类文件对象 stderr

《python基础教程(第二版)》学习笔记 字典(第4章)

<python基础教程(第二版)>学习笔记 字典(第4章)创建字典:d={'key1':'value1','key2':'value2'}lst=[('key1','value1'),('key2','value2')]; d=dict(lst)d=dict(key1='value1', key2='value2')字典基本操作:d={'key1':'value1','key2':'value2'}; len(d) ==> 2 #字典中的键值对数量d={'key1':'value1','

【Python基础教程第2版】——第一讲:基础知识

1.长字符串:(用三引号如'''或者"""来引起来) >>> print """This is a very log string.It continues here.And it's not over yet."Hello world!"""" This is a very log string.It continues here.And it's not over yet.&

电子书 html5与css3基础教程第8版.pdf

内容简介 <HTML5与CSS3基础教程(第8版)>自第1版至今,一直是讲解HTML和CSS入门知识的经典畅销书,全面系统地阐述HTML5和CSS3基础知识以及实际运用技术,通过大量实例深入浅出地分析了网页制作的方方面面.全新第8版不仅介绍了文本.图像.链接.列表.表格.表单等网页元素,还介绍了如何为网页设计布局.添加动态效果等,另外还涉及调试和发布. <HTML5与CSS3基础教程(第8版)>提供了一个强大的配套网站,上面列出了书中的完整代码示例以及更多优秀实例及进阶参考资料,以