Java 和 Object-c的区别

## 类的声明部分和实现部分

oc的创建是command+n的按钮,然后选择os-x 里面的Cocoa classoc的声明和实现是在不同的文件中,声明是在头文件.h文件中,实现是在.m(message的缩写)的文件中,

Phone.h

//
//  Phone.h
//  ReviewObjectC
//
//  Created by 千 on 16/9/8.
//  Copyright © 2016年 kodulf. All rights reserved.
//

//头文件中是声明

#import <Foundation/Foundation.h>

@interface Phone : NSObject
{
    //声明成员变量,成员变量一定要以下划线开头
    @public
    CGFloat _screenSize;
    NSString *_color;
    CGFloat _memory;
}

- (void)makeCallToSomeone : (NSString *)someone;
- (void)sendMessage : (NSString *)message toReceiver:(NSString *) receiver;
+ (void)printData : (NSString *)data;
@end


phone.m

//
//  Phone.m
//  ReviewObjectC
//
//  Created by 千 on 16/9/8.
//  Copyright © 2016年 kodulf. All rights reserved.
//

//这里是实现
#import "Phone.h"

@implementation Phone
- (void)makeCallToSomeone:(NSString *)someone
{
    NSLog(@"给%@打电话",someone);
}

- (void)sendMessage:(NSString *)message
         toReceiver:(NSString *)receiver
{
    NSLog(@"Receiver:%@\n%@",receiver,message);
}

//静态的方法,即类方法
+ (void)printData:(NSString *)data
{
    NSLog(@"类方法(静态方法)输出了%@",data);
}

- (NSString *)description
{
    return [NSString stringWithFormat:@"颜色:%@, 屏幕大小:%f, 内存:%f ", _color,_screenSize,_memory];
}

@end


相同点和不同点:


类都是集成了基础类,例如java中是object,oc里面就是NSObject

可以将变量声明为public 活着private,和java中不一样的是要用@public @private来做

java中的类的变量没有太多的要求但是类变量必须最好以m开头,oc中的类的变量必须是以_下划线来开头应该也就是建议的以下划线开头

java中的toSting()方法,oc中就有一个description()的方法和它相对应

java中的实例的变量的调用是点phone.color,oc中是->,phone->_color

java中的实例的方法的调用是点phone.hello(),oc中是通过[ ]中括号来做的[phone hello],所以是创建实例的new方法也是一样的

java中导入的类的地址,oc中导入的是类的头文件

java中的普通方法不用修饰,累方法是用static,oc中的类中的普通方法是用-号来表示,如果是类方法就是用+号

java中调用普通方法,也就是对象方法需要使用对象,调用类方法,需要使用类名,这个和oc一样一样的

java中的常量是用的final来修饰的,oc中是用final来修饰的?,这个条是不是java和c的区别吧


//
//  main.m
//  ReviewObjectC
//
//  Created by 千 on 16/9/7.
//  Copyright © 2016年 kodulf. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "Phone.h"
//上面引入的一定要是。h文件

int sum(int numa,int numb){
    return numa+numb;
}
//oc字符串


int main(int argc, const char * argv[]) {
    @autoreleasepool {
        // insert code here...
//        NSLog(@"Hello, World!");
//        printf("%s-%s-%s","2016","09","08");
//        int result = sum(5,10);
//        NSLog(@"结果=%d",result);
        
        Phone *phone = [Phone new];
        //在哪的外部不允许直接给属性修改,其实就是相当于java中的封装
        phone->_color = @"黑色";
        phone->_memory=123;
        phone->_screenSize=999;
        
        NSLog(@"%@",phone);
        //description 就相当于java中的toString
        [phone sendMessage:@"你好" toReceiver:@"收件人"];
        [phone makeCallToSomeone:@"kodulf"];
        
        //静态方法(即类方法的调用)
        [Phone printData:@"hello static method"];
        
        
    }
    return 0;
}



字符串,数组,和字典:

//和java的区别
//可变数组相当于java中的ArrayList,可变字典相当于java中的hashmap


//        0:不可变字符串的创建
//        不可变字符串指的是字符和长度不可变。但是地址是可变的。
//        可以直接创建NSString *string = @"string";
//        也可以通过[NSString stringWithFormat:@"%@", @"hello"];
//        string = @"bb";
//        NSString newString = @"bb";
//        这个时候string 和newString的地址是一样的
//        这个和java一样

//2:拼接,java直接使用+的符号,oc有三种方法,
//第一种是使用格式化的方法
//第二种是stringByAppendingString
//第三种是stringByAppendingFormat

//5:字符串比较
//和java一样的==比较的是地址,
//正式的判断两个字符的值是否相等的是 if([stringcompare1 compare:stringcompare2] == NSOrderedSame)
//其他的属性例如,以什么开始,hasprefix,以什么结束hassuffix,长度,大写都和java很类似的。

//数组的获取某个位置上面的值的方法可以和java一样array[0]这样,也可以是[nsarray2 objectAtIndex:0]

//注意方法有多个参数的时候,中间不要逗号隔开,这个和java有区别
//+(instancetype)initPersonWithName:(NSString *)name age:(NSUInteger)mage;

//0:不可变的字典的创建,一定要注意的是使用dictionaryWithObjectsAndKeys这个创建的时候是value key的形式来添加的和java不一样,但是使用最简方式创建的时候就是和java一样的,key value的形式,其实可以看上面的方法的名字也就明白了
// 获取指定的值,可以dic[@"key"]这个来做
//不可变字典可以获取对应value的key,java中没有这种方法。
//NSDictionary *dic5 = @{@"key1":@"value2",@"key2":@"value2"};
//NSArray *allkeysForOneValueArray = [dic5 allKeysForObject:@"value2"];
//NSLog(@"所有的value是value2的key:%@",allkeysForOneValueArray);


//和java中的preference一样,是持久化存取的。
void nsUserDefaultTest(){
    //用户设置的读取和设置
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    
    NSString *string = @"www.baidu.com";
    //添加
    [defaults setObject:string forKey:@"webset"];
    [defaults synchronize];//同步一下
    NSString *resultString = [defaults objectForKey:@"webset"];
    NSLog(@"result : %@",resultString);
    
    //将所有的键值对都打印出来
    NSDictionary *dic = [defaults dictionaryRepresentation];
    NSLog(@"用户默认的设置的所有的键值对:%@",dic);
    //移除
    [defaults removeObjectForKey:@"webset"];
    
}


//归档和解档achiver unachiver,数据持久化的方式,
//一种是plist文件一种是nsuserdefault,这两种都是操作的系统给的类型,例如字典和数组
//现在有一种可以自定义的类型的存储,这个是不是有点像java的serialization?

//归档achiver的时候,也就是序列化的时候,会自动的调用这个方法
//- (void)encodeWithCoder:(NSCoder *)coder
//{
//    [coder encodeObject:_name forKey:@"name"];
//    [coder encodeInteger:_age forKey:@"age"];
//    [coder encodeObject:_sex forKey:@"sex"];
//}
//
接档unachiver
//- (instancetype)initWithCoder:(NSCoder *)coder
//{
//    self = [super init];
//    if(self){
//        _name = [coder decodeObjectForKey:@"name"];
//        _age = [coder decodeIntegerForKey:@"age"];
//        _sex = [coder decodeObjectForKey:@"sex"];
//    }
//    return self;
//}

//在相应的类中,要进行归档必须要实现协议nscoding,正式的协议就是java里面的接口,和java里面要实现序列化就要实现serilization的接口一样,这里要实现nscoding
//@interface Person : NSObject <NSCoding>

void guidanjiedang(){
    Person *person = [[Person alloc] init];
    person.name = @"Tom";
    person.age = 20;
    person.sex = @"male";
    //归档器的类叫做NSKeyedArchiver,里面有一个类方法
    NSData *personData = [NSKeyedArchiver archivedDataWithRootObject:person];
    NSLog(@"二进制:%@",personData);
    //写入到文件中
    [personData writeToFile:@"/Users/JiYi2013/Desktop/guidang" atomically:YES];
    
    //从文件中读取,二进制,然后转化为类
    personData = [NSData dataWithContentsOfFile:@"/Users/JiYi2013/Desktop/guidang"];
    Person *unachiverperson2 = [NSKeyedUnarchiver unarchiveObjectWithData:personData];
    NSLog(@"unachiver解档:%@",unachiverperson2);
    
    
    //多个类型的归档和解档
    Person *person2 = [[Person alloc] init];
    person2.name =@"java";
    person2.age = 20;
    person2.sex = @"null";
    
    NSMutableData *mutabledata = [NSMutableData data];
    NSKeyedArchiver *personMutableAchiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:mutabledata];
    [personMutableAchiver encodeObject:person forKey:@"person"];
    [personMutableAchiver encodeObject:person2 forKey:@"person2"];
    //一定要结束归档,不然会一只归档
    [personMutableAchiver finishEncoding];
    NSLog(@"%@",mutabledata);
    
    //多个类型的解档
    NSKeyedUnarchiver *personMutableUnachiver = [[NSKeyedUnarchiver alloc]initForReadingWithData:mutabledata];
    Person *decodeperson = [personMutableUnachiver decodeObjectForKey:@"person"];
    Person *decodeperson2 = [personMutableUnachiver decodeObjectForKey:@"person2"];
    NSLog(@"解档:反序列化:person:%@",decodeperson);
    NSLog(@"解档:反序列化:person2:%@",decodeperson2);
}


int main(int argc, const char * argv[]) {
    //+++++++++++++注意main 方法是在load 和initlize中间调用,但是main中的autoreleasepool 是在initlize之后调用的++++++++++++++++++++
     NSLog(@"Main 方法被执行了");
    @autoreleasepool {
        //load 和initlize 相当于是java 中的静态代码块,构造代码块类似,load 相当于是静态代码块,initlize 相当于是构造代码块
        //http://blog.csdn.net/rodulf/article/details/52748295
        //java中的执行顺序:(优先级从高到低。)静态代码块>mian方法>构造代码块>构造方法。
        
        
        //先根据创建一个parent 类,然后是child类,
        //然后是child的分类,command+n,然后选择object-c file,然后是 class child,
    
        //load方法是一个类方法,是会被我们系统自动调用的,而这个方法的调用就是看文件是否被装载,只要是在我们compile source中出现的,总是会被我们的程序装载的,load方法总是在main函数之前被调用的。
        //compile source 可以通过点击左侧的蓝色的标志的,然后点击build pharse,然后点击compile source
        
        //这个load 就相当于是java中的静态代码块
        
        //在parent ,child类中重写,在child分类load中重写,最后调用的顺序是parent -》child-》child的分类,注意了所有的子类执行完了,才执行分类里面的load方法,分类一定是这里面最后调用的。
        //load方法是线程安全的,使用了锁
        
        //inilize main函数调用之后,只会调用一次,就是惰性调用机制,有利于去节约资源
        //inilize主要用来初始化全局变量和静态变量的,看名字就知道了
        
        //主要应用于不方便在编译器进行初始化的对象进行赋值
        //NSMutableArray 依赖于runtime的消息发送
        
        
        Child *child =[[Child alloc]init];
    }
    return 0;
}

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        //分类用来对类进行扩展,java中的自定义view有点类似
        //例如nsstring  没有反转字符串的方法的
        //command+n, 选择object-c file,然后在file type 选择category,下面的class 写入nsstring
        //@interface NSString (Helper)
        //调用的时候要先引入,例如这里是#import "NSString+Helper.h"
        
        NSString *string = @"0123456789";
        NSLog(@"反转前 %@,%p",string,string);
//        string = [string reverse];//注意这里需要string重新指向这个新的地址
//        NSLog(@"反转后 %@,%p",string,string);
        NSString *newString = [string reverse];
        NSLog(@"反转后 %@,%p",newString,newString);
        
    }
    return 0;
}

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        //oc 日期操作,和java几乎是一模一样,有区别的是这里的Date是直接格林尼治时间,java直接是系统的时间。
        NSDate *date = [NSDate date];
        NSLog(@"%@",date);//格林尼治时间
        
        //如何获取往前,往后的时间
        date = [[NSDate alloc] initWithTimeInterval:60 sinceDate:date];
        NSLog(@"60 秒以后的时间%@",date);//注意这里是60秒,而不是毫秒
    
        //进行时区的转换,首先获取系统的当前的时区
        NSTimeZone *zone = [NSTimeZone systemTimeZone];
        NSInteger interval = [zone secondsFromGMT];//获取时间差
        NSDate *localDate = [date dateByAddingTimeInterval:interval];
        NSLog(@"本地时间:%@",localDate);
        
        //如何对两个日期,进行日期的比较
        NSDate *currentDate =[NSDate date];
        NSDate *laterDate = [[NSDate alloc] initWithTimeInterval:60*60 sinceDate:currentDate];
        NSDate *earlierDate = [[NSDate alloc] initWithTimeInterval:-60 sinceDate:currentDate];
        
        if([currentDate laterDate:laterDate]){//这个方法说的是后面的是
            NSLog(@"currentDate: %@日期比laterDate:%@晚",currentDate,laterDate);
        }
        
        if([currentDate earlierDate:earlierDate]){
            NSLog(@"currentDate: %@日期比earlierDate:%@早",currentDate,earlierDate);
        }
        //通过compare来比较
        if([currentDate compare:earlierDate] ==NSOrderedDescending){
            NSLog(@"晚");
        }
        
        //nsdate 和nsstring的比较
        NSDate *date1 = [NSDate date];
        //日期格式化对象
        NSDateFormatter *dateFormatter
        = [[NSDateFormatter alloc] init];
        [dateFormatter setDateFormat:@"yyyy年MM月dd HH:mm:ss zzz"];//zzz表示时区,注意标准的应该是yyyy-MM-dd HH:mm:ss zzz,这里使用年,月是为了看的清楚一些。
        NSString *dateString = [dateFormatter stringFromDate:date1];
        NSLog(@"%@",dateString);
        
        dateString = @"2016年01月01 18:18:18";
        dateFormatter =[[NSDateFormatter alloc] init];
        [dateFormatter setDateFormat:@"yyyy年MM月dd HH:mm:ss"];
        date1 = [dateFormatter dateFromString:dateString];
        NSLog(@"%@",date1);
    
    }
    return 0;
}



单例模式里面的同步考虑,同步锁和java一样jcd是object c 的。http://blog.csdn.net/rodulf/article/details/52750739

//
//  User.m
//  SingleInstanceDemo
//
//  Created by 千雅爸爸 on 16/10/7.
//  Copyright © 2016年 kodulf. All rights reserved.
//

#import "User.h"

@implementation User
//全局可见的
static User *user = nil;

//一般是以default或者是shared开头
+(instancetype)sharedUser{
    //判断有没有对象实例,如果有了,那么就不去创建了
    //if(!user){
    //    user = [[self alloc]init];
    //}
    //如果考虑到多线程和同步的问题。有两种方法
    //1:互斥锁(比较消耗资源)
    //2:jcd的方式
    
    //互斥锁和java中的差不多,jcd java中没有
    
    //1:互斥锁
    //@synchronized (self) {
    //    if(!user){
    //        user = [[self alloc]init];
    //    }
    //}
    
    //2.jcd
    static dispatch_once_t onceToken;//是否只能执行一次
    dispatch_once(&onceToken, ^{
            if(!user){
                user = [[self alloc]init];
            }
    });
    
    
    return user;
}

//如果用户非要用alloc init 去创建的话
+(instancetype)allocWithZone:(struct _NSZone *)zone{
    static dispatch_once_t onceToken;//是否只能执行一次
    dispatch_once(&onceToken, ^{
        if(!user){
            user = [super allocWithZone:zone];
        }
    });
    return user;
}

//copy 直接返回就好了
-(id)copy{
    return user;
}
//mutableCopy也直接返回就好了
-(id)mutableCopy{
    return user;
}


- (NSString *)description
{
    return [NSString stringWithFormat:@"username=%@,age=%d", _username,_age];
}
@end
</pre><p></p><a target=_blank target="_blank" href="http://blog.csdn.net/rodulf/article/details/52750955">http://blog.csdn.net/rodulf/article/details/52750955</a><pre code_snippet_id="1874608" snippet_file_name="blog_20161007_12_7616382" name="code" class="csharp">Blcok
1.Java代码说明blcok
就是Java中匿名内部类,而匿名内部类的好处是代码更清晰
例如
button btn = new Button().setListener(newListener(){
//  这里写上监听的代码,这样就可以很直观的观察到这个btn要干啥了
//  例如这里写个发送邮件的代码,这样人们就知道你这按钮是点击后是发    //送邮件的功能
});
 


http://blog.csdn.net/rodulf/article/details/52751378

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        
        //oc的协议,正式的协议就是java中的接口
        //创建object -c file,file type 为protocol,
        //创建后,只有h文件,没有m文件,只是申明
        //尖尖括号括起来的也是协议<NSObject>,代表父协议
        
        //遵守协议,首先要在Person.h文件中引入#import "PersonProtocol.h"
        //然后是在@interface Person : NSObject <PersonProtocol>

        //和java 最大的不同是,这个协议可以实现或者不实现,可以通过@required来决定必须实现,@optional表示可以选择实现或者不实现,这个是和java 不同的
        
        //@required
        //-(void)eat;
    
        //@optional
        //-(void)work;
        //-(void)play;
        

        Person *person = [[Person alloc] init];
        [person eat];
        
        //继承person来创建一个police
        //创建一个警察的协议policeProtocol,里面有一个catchThief
        //然后创建小偷类,小偷的协议
        Police *police = [[Police alloc] init];
        [police catchThief];
        
        Thief *thief = [[Thief alloc]init];
        [thief steal];
        
        //可以让一个类去遵守多个协议,这个和java 是一样的
        
    }



  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值