黑马程序员--ios基础--oc语言--类和对象

时间:2022-12-22 00:30:47
------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------  一.定义oc的类核创建oc的对象 1.类的声明 代码编写 定义一个类,拥有2个属性 类名、属性的命名规则:标示符的规则 类名的命名规范:有意义、驼峰标识、首字母大写
成员变量 @interface的大括号{}中声明的变量 @interface的大括号和函数的大括号是不一样的 默认会初始化为0
@public @public可以让对象的属性被外界访问
NSObject 加上:NSObject的目的是让类具备创建对象的能力   方法(行为):方法名、参数、返回值(声明、实现) 只要是oc对象的方法,必须以减号-开头 oc 方法中任何数据类型都必须用()括住 oc方法中的():括住数据类型
#import <Foundation/Foundation.h>

// 完整地写一个函数:函数的声明和定义(实现)
// 完整地写一个类:类的声明和实现

// 1.类的声明
// 声明对象的属性、行为
// : NSObject 目的是:让Car这个类具备创建对象的能力
@interface Car : NSObject
{
@public
int wheels; // 轮胎个数
int speed; // 时速(xxkm/h)
}

- (void)run;

@end



2.类的实现
// 2.类的实现
// 用来实现@inteface中声明的方法
@implementation Car
// 方法的实现

- (void)run
{
NSLog(@"车子跑起来了");
}

@end


3.创建对象 代码编写 main函数的代码分析、内存分析(对象在内存中有成员) []每次都会创建出新的对象,并且返回对象的地址,那么就应该用一个指针变量保存对象的地址 设置对象的属性
int main()
{
Car *p = [Car new];

// 给p所指向对象的wheels属性赋值
p->wheels = 3;
p->speed = 50;

return 0;
}


4.创建多个对象
    Car *p2 = [Car new];
p2->wheels = 5;
p2->speed = 300;


5.面向对象封装的好处
  • 更加结印人类的思考方式
  • 只需要关注对象,不需要关注步骤
6.对象与函数参数 对象成员变量作为函数参数 指向对象的指针作为函数参数
  • 修改指向对象的成员
  • 修改指针的指向

#import <Foundation/Foundation.h>

@interface Car : NSObject
{// 成员变量
@public
int wheels;
int speed;
}

- (void)run;
@end

@implementation Car
- (void)run
{
NSLog(@"%d个*,速度为%dkm/h的车子跑起来", wheels, speed);
}
@end


void test(int w, int s)
{
w = 4;
s = 80;
}

void test1(Car *newC)
{
newC->wheels = 5;
}

void test2(Car *newC)
{
Car *c2 = [Car new];
c2->wheels = 5;
c2->speed = 60;

newC = c2;
newC->wheels = 6;
}

int main()
{
Car *c = [Car new];
c->wheels = 4;
c->speed = 77;

//test(c->wheels, c->speed);
//test1(c);
test2(c);

[c run];

return 0;
}




二.类的声明和实现 1.@interface和@implementation的分工 2声明和定义多个类 3.常见错误
  • 只有类的声明,没有类的实现
  • 漏了@end
  • @interface和@implementation嵌套
  • 两个类的声明嵌套
  • 成员变量没有写在括号里面
  • 方法的声明写在大括号里面
#import <Foundation/Foundation.h>

@interface Person : NSObject
@end

@interface Car : NSObject
{// 成员变量\实例变量
//int wheels = 4; 不允许在这里初始化
//static int wheels; 不能随便将成员变量当做C语言中的变量来使用
@public
int wheels;
}

- (void)run;
- (void)fly;
@end

int main()
{
// wheels = 10;
/*
Car *c = [Car new];
c->wheels = 4;
//run();

[c run];
*/

void test2();

test2();

return 0;
}

@implementation Car

- (void) fly
{

}

/*
void test2()
{
NSLog(@"调用了test2函数-%d", wheels);
}*/

void test()
{
NSLog(@"调用了test函数");
}

- (void)run
{
test();
NSLog(@"%d个*的车跑起来了", wheels);
}
@end


4.语法细节
  • 成员变量不能在{}中进行初始化、不能被直接拿出去访问
  • 方法不能当作函数一样调用
  • 成员变量、方法不能用static等关键字修饰
  • 类的实现可写在main函数的后面
5.oc方法和函数的区别 oc方法职能声明在@interface和@end之间,只能实现在@implementation和@end之间。 c 函数不属于类,跟类没有联系,c函数值归定义函数的文件所有 c函数不能访问oc对象的成员 6.oc的方法注意 方法只有声明,没有实现(经典错误) 方法没有声明,只有实现 编译的时候:访问没有的成员变量直接报错,访问没有的方法,只是警告 7.@implementation 没有@interface,只有@implementation,也是能成功定义一个类的 @implementation中不能声明和@interface一样的成员变量 练习代码:

#import <Foundation/Foundation.h>

typedef enum {
SexMan,
SexWoman
} Sex;

typedef struct {
int year;
int month;
int day;
} Date;


typedef enum {
ColorBlack,
ColorRed,
ColorGreen
} Color;

@interface Dog : NSObject
{
@public
double weight; // 体重
Color curColor; // 毛色
}

- (void)eat;
- (void)run;
@end

@implementation Dog
- (void)eat
{
// 每吃一次,体重就加1
weight += 1;
//weight = weight + 1;
NSLog(@"狗吃完这次后的体重是%f", weight);
}

- (void)run
{
weight -= 1;
NSLog(@"狗跑完这次后的体重是%f", weight);
}
@end


@interface Student : NSObject
{
@public
Sex sex; // 性别
Date birthday; // 生日
double weight; // 体重(kg)
Color favColor; // 最喜欢的颜色
char *name;

// 重点:狗
Dog *dog;
}
- (void)eat;
- (void)run;
- (void)print;

- (void)liuDog;
- (void)weiDog;
@end

@implementation Student

- (void)liuDog
{
// 让狗跑起来(调用狗的run方法)
[dog run];
}

- (void)weiDog
{
// 让狗吃东西(调用狗的eat方法)
[dog eat];
}

- (void)print
{
NSLog(@"性别=%d, 喜欢的颜色=%d, 姓名=%s, 生日=%d-%d-%d", sex, favColor, name, birthday.year, birthday.month, birthday.day);
}

- (void)eat
{
// 每吃一次,体重就加1
weight += 1;
//weight = weight + 1;
NSLog(@"学生吃完这次后的体重是%f", weight);
}

- (void)run
{
weight -= 1;
NSLog(@"学生跑完这次后的体重是%f", weight);
}
@end

int main()
{
Student *s = [Student new];

Dog *d = [Dog new];
d->curColor = ColorGreen;
d->weight = 20;
s->dog = d;


[s liuDog];

[s weiDog];
return 0;
}


void test()
{
Student *s = [Student new];
s->weight = 62;

// 性别
s->sex = SexMan;

// 生日
Date d = {1990, 9, 10};
s->birthday = d;

s->name = "ptt";

/*
s->birthday.year = 2011;
s->birthday.month = 9;
s->birthday.day = 10;
*/

// 喜欢的颜色
s->favColor = ColorBlack;
/*
[s eat];
[s eat];

[s run];
[s run];
*/

[s print];
}




三.方法 1.不带参数的方法 2.带一个参数的方法 3.带多个参数的方法 4.方法名注意
  • 冒号也是方法名的一部分
  • 同一个类中不允许两个对象方法同名
@interface JiSuanQi : NSObject

// 方法名:pi
- (double)pi;

// OC方法中,一个参数对应一个冒号
// 方法名:pingFang:(冒号也是方法名的一部分)
- (int)pingFang:(int)num;

//- (int)sum:(int)num1 :(int)num2;
// 方法名:sumWithNum1:andNum2:
- (int)sumWithNum1:(int)num1 andNum2:(int)num2;


//- (int)sumWithNum1:(int)num1 andNum2:(int)num2 andNum3:(int)num3;
@end

@implementation JiSuanQi

- (double)pi
{
return 3.14;
}

- (int)pingFang:(int)num
{
return num * num;
}

//- (int)sum:(int)num1 :(int)num2
- (int)sumWithNum1:(int)num1 andNum2:(int)num2
{
return num1 + num2;
}
@end

int main()
{
JiSuanQi *jsq = [JiSuanQi new];


int a = [jsq sumWithNum1:20 andNum2:5];
//int a = [jsq sum:10 :5];

//int a = [jsq pingFang:10];

//double a = [jsq pi];
NSLog(@"%i", a);

return 0;
}


匿名对象 属性访问 方法调用
#import <Foundation/Foundation.h>
@interface Car : NSObject
{
@public
int speed;
}
- (void)run;
@end

@implementation Car

- (void)run
{
NSLog(@"速度为%d的车子跑起来了", speed);
}

@end


int main()
{
/*
Car *c;
c = [Car new];
c->speed = 250;

[c run];*/

[Car new]->speed = 300;

[[Car new] run];

//Car *c = [Car new];

return 0;
}