精华内容
下载资源
问答
  • oc里面向对象的思维是一个将代码生活化的思想,所以今天打算用oc面向对象的思维来编写一个电影院购票系统! 思路:电影院购票——〉直接就可以浓缩为一句话:去电影院买票看电影。  其中有3个类。电影院,票...

    iOS开发中的内存管理问题:在这我简要概述一下,详细讲的话内容挺多,而且是作为一个ios开发人员,或ios开发爱好者,这是必须了解的:
    Objective-c中提供了两种内存管理机制MRC(MannulReference Counting)和ARC(Automatic Reference Counting),分别提供对内存的手动和自动管理,来满足不同的需求。其实arc 内部机制原理也是来源于mrc ,arc 是在 iOS 5/ Mac OS X 10.7 开始导入,利用 Xcode4.2 可以使用该机能。arc的首要目的就是让代码简洁化,编程简单化,开发更顺心应手,减少不必要的小问题小疏忽;顾名思义,自动引用计数管理,关于内存的申请,使用和释放过程都交给系统自动实现,我们可也不用关系里面的过程,但是事实上还是mrc的原理,只是是系统帮我们做了管理;
    mrc,手动引用计数器管理,是在我们申请到某一块内存,在使用之后,要手动释放,释放机理涉及到计数器问题,如果未释放内存,会造成内存的浪费,俗称内存泄露,甚至引起很多未知的错误结果,这对程序有威胁很大,但是,何时释放,怎么释放,注意哪些问题,很有讲究,这就是mrc的不便之处,也是苹果推出arc的缘由;
    mrc的具体机理,计数器是什么,在程序过程中的变化,在达到什么程度会释放内存,怎么操作;建议查阅相关文档;
    mrc ,在代码上下形式主要表现为,调用该对象时,要做retain操作,使用完成后要release,最后还要重写dealloc方法,对该类的所有对象做释放,所以在mrc的代码会有autorelease,retain,release等词语,
    而arc不允许有这些词汇,应为这些操作都由系统自动完成。
    引用计数器
    1.和内存管理相关的方法
    1)alloc 引用计数器自动设为1
    2)retain 引用计数器+1 返回了经过+1以后的当前实例对象
    3)release 引用计数器-1,并不一定是释放
    4)retainCount 获取引用计数器的值
    5)dealloc 当实例对象被销毁之前,系统自动调用。
    一定要调[super dealloc]
    和内存管理相关的名词
    1)僵尸对象:此对象被销毁,不能再使用,不能给它发送任何消息
    2)野指针:指向僵尸对象(不可用的内存)的指针,给野指针发送消息将会产生不可控的后果。
    3)空指针:没有指向任何对象的指针,给空指针发消息不会产生任何行为
    内存管理原则
    1.如果你想持有某个对象,就必须负责让做一次retain操作,引用计数器+1.
    2.如果你想放弃对某个对象的持有权,就要负责让其做一次release操作,引用计数器-1.
    3.谁retain,谁release。
    说到最后,如过是新手的话建议用mrc来写,这样可以清晰的认识oc的内存管理机制,避免一些不必要的失误


    展开全文
  • [数据结构与算法]基数排序

    千次阅读 2014-10-20 10:08:01
    每一个算法都是一种智慧凝聚或萃取,值得我们学习从而提高自己,开拓思路,更重要是转换思维角度。其实,我们大多数人都活在“默认状态”下。没有发觉自己独特可设置选项-----思想。言归正传(呵呵!恢复默认...

    编程论到极致,核心非代码,即思想。

    所以,真正的编程高手同时是思想独到及富有智慧(注意与聪明区别)的人。

    每一个算法都是一种智慧的凝聚或萃取,值得我们学习从而提高自己,开拓思路,更重要的是转换思维角度。

    其实,我们大多数人都活在“默认状态”下。没有发觉自己的独特可设置选项-----思想。

    言归正传(呵呵!恢复默认状态),以下学习基数排序。

    【1】基数排序

    以前研究的各种排序算法,都是通过比较数据大小的方法对欲排数据序列进行排序整理过程。

    而基数排序却不再相同,那么,基数排序是采用怎样的策略进行排序的呢?

    简略概述:基数排序是通过“分配”和“收集”过程来实现排序。而这个思想该如何理解呢?请看以下例子。

    (1)假设有欲排数据序列如下所示:

    73  22  93  43  55  14  28  65  39  81

    首先根据个位数的数值,在遍历数据时将它们各自分配到编号0至9的桶(个位数值与桶号一一对应)中。

    分配结果(逻辑想象)如下图所示:

    分配结束后。接下来将所有桶中所盛数据按照桶号由小到大(桶中由顶至底)依次重新收集串起来,得到如下仍然无序的数据序列:

    81  22  73  93  43  14  55  65  28  39

    接着,再进行一次分配,这次根据十位数值来分配(原理同上),分配结果(逻辑想象)如下图所示:

    分配结束后。接下来再将所有桶中所盛的数据(原理同上)依次重新收集串接起来,得到如下的数据序列:

    14  22  28  39  43  55  65  73  81  93

    观察可以看到,此时原无序数据序列已经排序完毕。如果排序的数据序列有三位数以上的数据,则重复进行以上的动作直至最高位数为止。

    那么,到这里为止,你觉得你是不是一个细心的人?不要不假思索的回答我。不论回答什么样的问题,都要做到心比头快,头比嘴快。

    仔细看看你对整个排序的过程中还有哪些疑惑?真看不到?觉得我做得很好?抑或前面没看懂?

    如果你看到这里真心没有意识到或发现这个问题,那我告诉你:悄悄去找个墙角蹲下用小拇指画圈圈(好好反省反省)。

    追问:观察原无序数据序列中73   93   43 三个数据的顺序,在经过第一次(按照个位数值,它们三者应该是在同一个桶中)分配之后,

    在桶中顺序由底至顶应该为73  93  43(即就是装的迟的在最上面,对应我们上面的逻辑想象应该是43  93  73),对吧?这个应该可以想明白吧?理论上应该是这样的。

    但是,但是,但是分配后很明显在3号桶中三者的顺序刚好相反。这点难道你没有发现吗?或者是发现了觉得不屑谈及(算我贻笑大方)?

    其实这个也正是基数排序稳定性的原因(分配时由末位向首位进行),请看下文的详细分析。

    再思考一个问题:既然我们可以从最低位到最高位进行如此的分配收集,那么是否可以由最高位到最低位依次操作呢? 答案是完全可以的。

    基于两种不同的排序顺序,我们将基数排序分为LSD(Least significant digital)或MSD(Most significant digital),

    LSD的排序方式由数值的最右边(低位)开始,而MSD则相反,由数值的最左边(高位)开始。

    注意一点:LSD的基数排序适用于位数少的数列,如果位数多的话,使用MSD的效率会比较好。

    MSD的方式与LSD相反,是由高位数为基底开始进行分配,但在分配之后并不马上合并回一个数组中,而是在每个“桶子”中建立“子桶”,将每个桶子中的数值按照下一数位的值分配到“子桶”中。

    在进行完最低位数的分配后再合并回单一的数组中。

    (2)我们把扑克牌的排序看成由花色和面值两个数据项组成的主关键字排序。

    要求如下:

    花色顺序:梅花<方块<红心<黑桃

    面值顺序:2<3<4<...<10<J<Q<K<A

    那么,若要将一副扑克牌排成下列次序:

    梅花2,...,梅花A,方块2,...,方块A,红心2,...,红心A,黑桃2,...,黑桃A。

    有两种排序方法:

    <1>先按花色分成四堆,把各堆收集起来;然后对每堆按面值由小到大排列,再按花色从小到大按堆收叠起来。----称为"最高位优先"(MSD)法。

    <2>先按面值由小到大排列成13堆,然后从小到大收集起来;再按花色不同分成四堆,最后顺序收集起来。----称为"最低位优先"(LSD)法。

    【2】代码实现

    (1)MSD法实现

    最高位优先法通常是一个递归的过程:

    <1>先根据最高位关键码K1排序,得到若干对象组,对象组中每个对象都有相同关键码K1。

    <2>再分别对每组中对象根据关键码K2进行排序,按K2值的不同,再分成若干个更小的子组,每个子组中的对象具有相同的K1和K2值。

    <3>依此重复,直到对关键码Kd完成排序为止。

    <4> 最后,把所有子组中的对象依次连接起来,就得到一个有序的对象序列。

    示例代码如下:

    #include<iostream>
    #include<malloc.h>
    using namespace std;
    
    int getdigit(int x,int d)  
    {   
        int a[] = {1, 1, 10};     //因为待排数据最大数据也只是两位数,所以在此只需要到十位就满足
        return ((x / a[d]) % 10);    //确定桶号
    }  
    
    void  PrintArr(int ar[],int n)
    {
        for(int i = 0; i < n; ++i)
            cout<<ar[i]<<" ";
        cout<<endl;
    }
    
    void msdradix_sort(int arr[],int begin,int end,int d)  
    {     
        const int radix = 10;   
        int count[radix], i, j; 
        //置空
        for(i = 0; i < radix; ++i)   
        {
            count[i] = 0;   
        }
        //分配桶存储空间
        int *bucket = (int *) malloc((end-begin+1) * sizeof(int));    
        //统计各桶需要装的元素的个数  
        for(i = begin;i <= end; ++i)   
        {
            count[getdigit(arr[i], d)]++;   
        }
        //求出桶的边界索引,count[i]值为第i个桶的右边界索引+1
        for(i = 1; i < radix; ++i)   
        {
            count[i] = count[i] + count[i-1];    
        }
        //这里要从右向左扫描,保证排序稳定性 
        for(i = end;i >= begin; --i)          
        {    
            j = getdigit(arr[i], d);      //求出关键码的第d位的数字, 例如:576的第3位是5   
            bucket[count[j]-1] = arr[i];   //放入对应的桶中,count[j]-1是第j个桶的右边界索引   
            --count[j];                    //第j个桶放下一个元素的位置(右边界索引+1)   
        }   
        //注意:此时count[i]为第i个桶左边界    
        //从各个桶中收集数据  
        for(i = begin, j = 0;i <= end; ++i, ++j)  
        {
            arr[i] = bucket[j]; 
        }       
        //释放存储空间
        free(bucket);   
        //对各桶中数据进行再排序
        for(i = 0;i < radix; i++)  
        {   
            int p1 = begin + count[i];         //第i个桶的左边界   
            int p2 = begin + count[i+1]-1;     //第i个桶的右边界   
            if(p1 < p2 && d > 1)  
            {
                msdradix_sort(arr, p1, p2, d-1);  //对第i个桶递归调用,进行基数排序,数位降 1    
            }
        }  
    } 
    
    void  main()
    {
        int  ar[] = {12, 14, 54, 5, 6, 3, 9, 8, 47, 89};
        int len = sizeof(ar)/sizeof(int);
        cout<<"排序前数据如下:"<<endl;
        PrintArr(ar, len);
        msdradix_sort(ar, 0, len-1, 2);
        cout<<"排序后结果如下:"<<endl;
        PrintArr(ar, len);
    } 
    /*
    排序前数据如下:
    12 14 54 5 6 3 9 8 47 89
    排序后结果如下:
    3 5 6 8 9 12 14 47 54 89
     */

    (2)LSD法实现

    最低位优先法首先依据最低位关键码Kd对所有对象进行一趟排序,

    再依据次低位关键码Kd-1对上一趟排序的结果再排序,

    依次重复,直到依据关键码K1最后一趟排序完成,就可以得到一个有序的序列。

    使用这种排序方法对每一个关键码进行排序时,不需要再分组,而是整个对象组。

    示例代码如下:

    #include<iostream>
    #include<malloc.h>
    using namespace std;
    
    #define   MAXSIZE   10000
    
    int getdigit(int x,int d)  
    {   
        int a[] = {1, 1, 10, 100};   //最大三位数,所以这里只要百位就满足了。
        return (x/a[d]) % 10;  
    }  
    void  PrintArr(int ar[],int n)
    {
        for(int i = 0;i < n; ++i)
        {
            cout<<ar[i]<<" ";
        }
        cout<<endl;
    }  
    void lsdradix_sort(int arr[],int begin,int end,int d)  
    {    
        const int radix = 10;   
        int count[radix], i, j; 
    
        int *bucket = (int*)malloc((end-begin+1)*sizeof(int));  //所有桶的空间开辟   
       
        //按照分配标准依次进行排序过程
        for(int k = 1; k <= d; ++k)  
        {  
            //置空
            for(i = 0; i < radix; i++)  
            {
                count[i] = 0;        
            }               
            //统计各个桶中所盛数据个数
            for(i = begin; i <= end; i++) 
            {
               count[getdigit(arr[i], k)]++;
            }
            //count[i]表示第i个桶的右边界索引
            for(i = 1; i < radix; i++) 
            {
                count[i] = count[i] + count[i-1];
            }
            //把数据依次装入桶(注意装入时候的分配技巧)
            for(i = end;i >= begin; --i)        //这里要从右向左扫描,保证排序稳定性   
            {    
                j = getdigit(arr[i], k);        //求出关键码的第k位的数字, 例如:576的第3位是5   
                bucket[count[j]-1] = arr[i]; //放入对应的桶中,count[j]-1是第j个桶的右边界索引 
                --count[j];               //对应桶的装入数据索引减一  
            } 
    
            //注意:此时count[i]为第i个桶左边界  
            
            //从各个桶中收集数据
            for(i = begin,j = 0; i <= end; ++i, ++j)  
            {
                arr[i] = bucket[j];    
            }        
        }     
        free(bucket);   
    }  
    
    void  main()
    {
        int  br[10] = {20, 80, 90, 589, 998, 965, 852, 123, 456, 789};
        cout<<"原数据如下:"<<endl;
        PrintArr(br,10);
        lsdradix_sort(br, 0, 9, 3);
        cout<<"排序后数据如下:"<<endl;
        PrintArr(br, 10);
    }
    /*
    原数据如下:
    20 80 90 589 998 965 852 123 456 789
    排序后数据如下:
    20 80 90 123 456 589 789 852 965 998
    */

    注意:以上两种方法我们均用数组模拟桶,关于数组模拟桶详细讲解请参考随笔《桶排序

    【3】基数排序稳定性分析

    基数排序是稳定性排序算法,那么,到底如何理解它所谓的稳定特性呢?

    比如:我们有如下欲排数据序列:

    下面选择LSD逻辑演示

    第一次按个位数值分配,结果如下图所示:


    然后收集数据结果如下:

    第二次按十位数值分配,结果如下图所示:

    然后收集数据结果如下:

    注意:分配时是从欲排数据序列的末位开始进行,逐次分配至首位。

    好吧!排序结束。相信一定一目了然。在此不作赘述。

    http://www.cnblogs.com/Braveliu/archive/2013/01/21/2870201.html

    展开全文
  • 说起C语言和C++之间最大区别,大多数书籍上写明是编程的思维不同,C语言是面向过程语言,而C++是面对对象语言。那什么是面向过程的思想? 什么是面对对象的思想? 面向过程思想 设计思路:–自顶向下、...

    C语言和C++语言关系

    说起C语言和C++之间的最大区别,大多数的书籍上写明是编程的思维不同,C语言是面向过程的语言,而C++是面对对象的语言。那什么是面向过程的思想? 什么是面对对象的思想?

    面向过程思想

    • 设计思路:
      –自顶向下、逐步求精。采用模块分解与功能抽象,自顶向下、分而治之。
    • 程序结构:
      – 按功能划分为若干个基本模块,形成一个树状结构。
      – 各模块间的关系尽可能简单,功能上相对独立;每一模块内部均是由顺序、选择和循环三种基本结构组成。
      – 其模块化实现的具体方法是使用子程序。
    • 优点:
      有效地将一个较复杂的程序系统设计任务分解成许多易于控制和处理的子任务,便于开发和维护。
    • 缺点
      – 可重用性差、数据安全性差、难以开发大型软件和图形界面的应用软件 –把数据和处理数据的过程分离为相互独立的实体。
      – 当数据结构改变时,所有相关的处理过程都要进行相应的修改。
      – 每一种相对于老问题的新方法都要带来额外的开销。
      – 图形用户界面的应用程序,很难用过程来描述和实现,开发和维护也都很困难。

    面对对象的方法

    对象

    • 一般意义上的对象:
      – 是现实世界中一个实际存在的事物。
      – 可以是有形的(比如一辆汽车),也可以是无形的(比如一项计划)。
      – 是构成世界的一个独立单位,具有独立性。有如下特征:
    • 静态特征:可以用某种数据来描述。
    • 动态特征:对象所表现的行为或具有的功能。
    • 面向对象方法中的对象:
      – 是系统中用来描述客观事物的一个实体,它是用来构成系统的一个基本单位。对象由一组属性和一组行为构成。
      – 属性:用来描述对象静态特征的数据项。
      – 行为:用来描述对象动态特征的操作序列。
    • 分类——人类通常的思维方法。
    • 分类所依据的原则——抽象
      – 忽略事物的非本质特征,只注意那些与当前目标有关的本质特征,从而找出事物的共性,把具有共同性质的事物划分为一类,得出一个抽象的概念。
      – 例如,石头、树木、汽车、房屋等都是人们在长期的生产和生活实践中抽象出的概念。
    • 面向对象方法中的"类":
      – 具有相同属性和服务的一组对象的集合
      – 为属于该类的全部对象提供了抽象的描述,包括属性和行为两个主要部分。
      – 类与对象的关系: 犹如模具与铸件之间的关系,一个属于某类的对象称为该类的一个实例。
    • 封装 :也就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。
      – 把对象的属性和服务结合成一个独立的系统单元。
      – 尽可能隐蔽对象的内部细节。对外形成一个边界(或者说一道屏障),只保留有限的对外接口使之与外部发生联系。
      – 继承对于软件复用有着重要意义,是面向对象技术能够提高软件开发效率的重要原因之一。
      – 定义:特殊类的对象拥有其一般类的全部属性与服务,称作特殊类对一般类的继承。
      – 例如:将轮船作为一个一般类,客轮便是一个特殊类。
    • 多态:多态是指在一般类中定义的属性或行为,被特殊类继承之后,可以具有不同的数据类型或表现出不同的行为。这使得同一个属性或行为在一般类及其各个特殊类中具有不同的语义。
    • 面向对象的软件工程
      – 面向对象的分析(OOA)
      – 面向对象的设计(OOD)
      – 面向对象的编程(OOP)
      – 面向对象的测试(OOT)
      – 面向对象的软件维护(OOSM)

    C++对C语言的强化

    1 namespace命名空间

     在C++中,名称(name)可以是符号常量、变量、宏、函数、结构、枚举、类和对象等等。为了避免,在大规模程序的设计中,以及在程序员使用各种各样的C++库时,这些标识符的命名发生冲突,
     标准C++引入了关键字namespace(命名空间/名字空间/名称空间/名域),可以更好地控制标识符的作用域。
     std是c++标准命名空间,c++标准程序库中的所有标识符都被定义在std中,比如标准库中的类iostream、vector
     等都定义在该命名空间中,使用时要加上using声明(using namespace std) 或using指示 (如std::string、std::vector).

    C中的命名空间
     在C语言中只有一个全局作用域
     C语言中所有的全局标识符共享同一个作用域
     标识符之间可能发生冲突
    C++中提出了命名空间的概念
     命名空间将全局作用域分成不同的部分
     不同命名空间中的标识符可以同名而不会发生冲突
     命名空间可以相互嵌套
     全局作用域也叫默认命名空间

    2 提高变量声明实用性

    #include "iostream"
    using namespace std;
    
    //C语言中的变量都必须在作用域开始的位置定义!!
    //C++中更强调语言的“实用性”,所有的变量都可以在需要使用时再定义。
    
    int main()
    {
    	int i = 0;
    
    	printf("ddd");
    	int k;
    	system("pause");
    	return 0;
    }
    

    3 register关键字增强

     register关键字 请求编译器让变量a直接放在寄存器里面,速度快,在c语言中 register修饰的变量 不能取地址,但是在c++里面做了内容,register关键字的变化
    register关键字请求“编译器”将局部变量存储于寄存器中C语言中无法取得register变量地址,在C++中依然支持register关键字C++编译器有自己的优化方式,不使用register也可能做优化。C++中可以取得register变量的地址,而这一点在C语言中是不能做到的。有几个点要注意:
     1 C++编译器发现程序中需要取register变量的地址时,register对变量的声明变得无效
      2 早期C语言编译器不会对代码进行优化,因此register变量是一个很好的补充。

    int main()
    {
    	register int a = 0; 
    	printf("&a = %x\n", &a);
    	system("pause");
    	return 0;
    }
    

    这行代码在C编译器是无法通过的,但在C++编译器中是可以通过的。

    4变量检测增强

     在C语言中,重复定义多个同名的全局变量是合法的,而在C++中,不允许定义多个同名的全局变量。C语言中多个同名的全局变量最终会被链接到全局数据区的同一个地址空间上。

    #include <stdio.h>
    	int g_var;
    	int g_var = 1;
    int main () {
    	system("pause");
    	return 0;
    }
    
    

    这种变量在C语言编译器中可以通过,但是具备二义性。C++直接拒绝这种二义性的做法。

    5 struct类型加强

    struct类型的加强:
     C语言的struct定义了一组变量的集合,C编译器并不认为这是一种新的类型 C++中的struct是一个新类型的定义声明。

    6 C++中所有的变量和函数都必须有类型

    在C语言中
     int f( );表示返回值为int,接受任意参数的函数
     int f(void);表示返回值为int的无参函数
    在C++中
      int f( );和int f(void)具有相同的意义,都表示返回值为int的无参函数。

    7 新增Bool类型关键字

    新增Bool类型关键字C++中的布尔类型
    C++在C语言的基本类型系统之上增加了bool
    C++中的bool可取的值只有true和false
    理论上bool只占用一个字节,
    如果多个bool变量定义在一起,可能会各占一个bit,这取决于编译器的实现。

    true代表真值,编译器内部用1来表示
    false代表非真值,编译器内部用0来表示
    
    bool类型只有true(非0)和false(0)两个值
    C++编译器会在赋值时将非0值转换为true,0值转换为false
    

    8 三目运算符功能增强

    #include <stdio.h>
    
    int main()
    {
    	int a = 10;
    	int b = 20;
    
    	//返回一个最小数 并且给最小数赋值成3
    	//三目运算符是一个表达式 ,表达式不可能做左值
    	(a < b ? a : b )= 30;
    
    	printf("a = %d, b = %d\n", a, b); 
    
    	system("pause");
    
    	return 0;
    }
    

    1)C语言返回变量的值 C++语言是返回变量本身,而变量本身在这个时候为一个数。所以
    C语言中的三目运算符返回的是变量值,不能作为左值使用,C++中的三目运算符可直接返回变量本身,因此可以出现在程序的任何地方(左边或者右边)。
    2)注意:三目运算符可能返回的值中如果有一个是常量值,则不能作为左值使用
    &emsp(a < b ? a : b )= 30;
    3)C语言如何支持类似C++的特性呢?
    在C++中会将(a < b ? a : b )= 30; ===> *(a < b ? &a : &b )= 30;

    展开全文
  • 面向对象和面向过程的区别 都是一种思想,思维方式 面向过程:"我应该如何完成?"然后一步一步的去实现就可以了 面向对象:"这件事我不想做,我应该找谁来完成?"关注的就是对象,而不是关注实现过程 面向对象依托于面向...

    面向对想

    面向对象和面向过程的区别

    • 都是一种思想,思维方式
    • 面向过程:"我应该如何完成?"然后一步一步的去实现就可以了
    • 面向对象:"这件事我不想做,我应该找谁来完成?"关注的就是对象,而不是关注实现过程
    • 面向对象依托于面向过程,二者相辅相成,都是一种解决问题的思路

    面向对象的优点

    • 可以将复杂的问题简单化
    • 面向对象更贴合于管理者,面向过程更贴合于执行者
    • 面向对象的思维方式更符合现实生活中人们的思维方式

    假如要造一辆汽车,面向过程就是一步一步的去解决问题,先去买橡胶,画图纸,造模具…等等.然而造汽车用面向对象思维来想就是,我先找一批人过来, 1个人去买橡胶,3人一起造轮胎,10人一起造模具, 20个人装配汽车等等,分工明确,每个人做每个人的事,分工明确,把造汽车这个复杂的问题简单化,更符合现实生活中人们的思维方式

    java中为我们提供了2个角色: 类 对象 实现程序的开发
    类: 表示一些对象的共性 | 特点 | 特征–>共性
    对象: 表示现实生活中的具体事务
    根据类创建对象,通过类和对象将程序与生活建立联系

    如何自定义类:

    修饰符 类名{
    	//成员变量
    	修饰符 数据类型 变量名 = 赋值;
    	
    	//成员方法:不被static修饰的方法就叫做成员方法
    	修饰符 返回值类型|void 方法名(参数列表){
    			功能体;
    		}
    	}
    
    public class Phone01 { 
    	//属性:成员变量
    	public/*修饰符*/ String/*数据类型*/ color;
    	//品牌
    	public String brand;
    	//价钱
    	public double price;
    	
    	//功能:成员方法
    	public /*修饰符*/void/*返回值类型,无返回值*/call(){
    		System.out.println("从前有一个人长得像电话,出门就被打了...");//功能体
    	}
    }
    

    类的测试
    1.导包:
    同包下的类不需要导包
    在java.lang包下的直接子内容不需要导包

    2.创建这个类型的引用|变量:–>创建对象
    引用数据类型 引用 = new 引用数据类型();
    new关键字就是创建对象

    3.根据对象名字|引用名使用某个对象的功能
    引用.功能名字();
    引用.属性名字

    class Phone{
    	//成员属性
    	//手机颜色
    	public String color;
    	//手机品牌
    	public String brand;
    	//手机价格
    	public String price;
    	//人
    	public String name;
    	//功能
    	public void charge(){
    		System.out.println(name+"给"+brand+color+"手机充电");
    	}
    }
    
    public class Phone01 {
    	public static void main(String[] args){
    		Phone phone =  new Phone();//引用数据类型 引用 = new 引用数据类型();  
    			//new关键就是创建对象
    			phone.name="小唐";//引用.属性名字
    			phone.brand="华为";//引用.属性名字
    			phone.color="翡冷翠";//引用.属性名字
    			
    			phone.charge();//引用.功能名字();
    			
    		}
    }
    

    自定义的引用数据类型可以作为方法的返回值类型,返回一个对应类型的对象
    下面的代码中return后面的cake返回了一个cake类型的对象
    然后引用功能,让他实现,现实生活中,我们做蛋糕做好了,也需要拿回去,所以必须要返回值.

    public class Cake {
    	//成员属性
    	//口味
    	public String taste;
    	//形状 
    	public String shape;
    	//尺寸
    	public int size;
    	//价钱
    	public double money;
    	//制作细节
    	public String details;
    	
    	//成员方法
    	//展示细节
    	public void info(){
    		System.out.println(taste+"-->"+shape+"-->"+size+"-->"+money+"-->"+details);
    	}
    }
    public class Caker {
    	//名字
    	public String name;
    	//性别
    	public boolean gender;  //true->男  false->女
    	//级别
    	public String level;
    	
    	//自定义的引用数据类型可以作为方法的返回值类型,返回一个对应类型的对象
    	//做蛋糕   : 动物奶油 
    	//返回值:要蛋糕   Cake     参数:要  口味   尺寸    价钱
    	public Cake make(String taste,int size,double price){ 
    		//制作蛋糕->创建一个蛋糕对象
    		Cake cake=new Cake();//引用数据类型 引用 = new 引用数据类型();  
    		cake.taste=taste;//引用.属性名字
    		cake.shape="java";//引用.属性名字
    		cake.size=size;//引用.属性名字
    		cake.money=price;//引用.属性名字
    		cake.details="100个鸡蛋";//引用.属性名字
    		return cake;//返回值返回一个蛋糕类型的对象
    	}
    }
    
    

    构造器

    • new关键字就是创建对象
    • 在堆中为对象开辟空间,成员属性跟随对象进入到堆中,并赋默认值
    • 调用这个类的构造器为对象初始化信息(第一次赋值就叫做初始化,及成员属性)
    • 将地址返回给引用

    构造器: 构造方法

    构造函数(java中不这么叫,没有函数这一说,都称之为方法)

    构造器就是一个特殊的方法

    • 构造器的作用:就是为对象初始化信息,不是用来创建对象的
    • 构造器的使用: 跟随new 使用
    • 构造器的定义
    修饰符 类名(参数列表){
    	构造器...
    }
    没有返回值类型,没有void,可以添加return
    方法名必须与类名一致,否则编译器报错.
    不能和static,final,abstract一起使用
    
    

    注意事项

    • 如果没有自定义的为类定义任何构造器,编译器会为你的类默认提供一个空构造(没有参数的构造器)
    • 如果有显示定义任何构造器,编译器就不会再为你提供任意构造器了
    • 构造器是一个方法,是方法就可以重载

    构造器的优点

    • 构造器可以帮助我们简化代码,在通过对象.属性之前,就可以提前为对象属性赋值
    • 构造器就是特殊的方法,特殊的创建方式,特殊的使用方式,特殊的作用,但是也是方法,所以有方法重载的特性

    如何在创建对象的时候指定匹配不同的构造器?

    				new 类型()-->匹配不同的参数列表
    
    public static void main(String[] args) {
    		//先创建对象
    		Dog dog=new Dog();  //()->构造器的参数列表
    		//手动赋值
    		dog.color="黄色";
    		dog.type="中华田园犬";
    		
    		//创建对象并且赋值
    		Dog dog2=new Dog("棕色","金毛");
    		dog.dog();
    		dog2.dog();
    		
    		
    		
    	}
    
    }
    class Dog{
    	public String color;
    	public String type;
    	
    	//构造器  空构造
    	public Dog(){
    		System.out.println("我是空构造");
    	}
    	
    	public Dog(String dogColor){
    		System.out.println("我是带1个参数的构造器");
    		color=dogColor;
    	}
    	
    	//带参构造  2个参数
    	public Dog(String dogColor,String dogType){
    		color=dogColor;
    		type=dogType;
    		System.out.println("我是带2个参数的构造器");
    	}
    	
    	//展示细节
    	public void dog(){
    		System.out.println(color+"---->"+type);
    	}
    	
    }
    
    

    说明:

    • 构造方法不能被显式调用。
    • 构造方法不能有返回值,因为没有变量来接收返回值
    展开全文
  • 算法

    2017-10-29 00:46:54
    编程论到极致,核心非代码,即思想。所以,真正编程高手同时是思想独到及富有智慧(注意与聪明区别人。每一个算法都是一种智慧凝聚或萃取,值得我们学习从而提高自己,开拓思路,更重要是转换思维角度。
  • (二)初遇面向对象

    2017-04-04 13:07:06
    一,Java面向对象概述1.1 面向对象和面向过程的区别 面向过程编程: 强调的是功能行为,体现的思路是一个功能是由一系列明确的有顺序的实现步骤来完成的。因为逻辑更抽象,代码运行的更快,一般使用在底层比较需要...
  • 面向过程与面向对象的区别 面向过程思想: 步骤清晰简单,第一步做什么,第二步做什么… 面对过程适合处理一些较为简单的问题 面向对象思想: 物以类聚,分类的思维模式,思考问题首先会解决问题需要哪些...
  • 基数排序

    2019-10-07 20:37:17
    每一个算法都是一种智慧凝聚或萃取,值得我们学习从而提高自己,开拓思路,更重要是转换思维角度。 其实,我们大多数人都活在“默认状态”下。没有发觉自己独特可设置选项-----思想。 言归正传(呵呵!恢复...
  • 面向过程的区别 面向过程思想 步骤清晰简单,第一步做什么,第二步做什么以及后续每一步都清清楚楚 面向过程适用于处理一些较为简单的问题 面向对象思想 物以类聚,分类的思维模式,思考问题首先会解决问题...
  • 排序——基数排序

    2016-08-23 15:57:01
    每一个算法都是一种智慧凝聚或萃取,值得我们学习从而提高自己,开拓思路,更重要是转换思维角度。 其实,我们大多数人都活在“默认状态”下。没有发觉自己独特可设置选项-----思想。 言归正传(呵呵!恢复...
  • 基数排序2

    2015-09-14 14:36:57
    每一个算法都是一种智慧凝聚或萃取,值得我们学习从而提高自己,开拓思路,更重要是转换思维角度。其实,我们大多数人都活在“默认状态”下。没有发觉自己独特可设置选项—–思想。言归正传(呵呵!恢复默认...
  • 每一个算法都是一种智慧凝聚或萃取,值得我们学习从而提高自己,开拓思路,更重要是转换思维角度。 其实,我们大多数人都活在“默认状态”下。没有发觉自己独特可设置选项-----思想。 言归正传(呵呵!恢复...
  • 【转载】基数排序

    2015-04-02 23:38:00
    每一个算法都是一种智慧凝聚或萃取,值得我们学习从而提高自己,开拓思路,更重要是转换思维角度。 其实,我们大多数人都活在“默认状态”下。没有发觉自己独特可设置选项-----思想。 言归正传(呵呵!恢复...
  • 【算法】基数排序

    2018-08-06 10:14:24
    编程论到极致,核心非代码,即思想。...每一个算法都是一种智慧凝聚或萃取,值得我们学习从而提高自己,开拓思路,更重要是转换思维角度。 其实,我们大多数人都活在“默认状态”下。没有发觉自己...
  • 8-3.基数排序详解

    2015-07-20 20:57:00
    每一个算法都是一种智慧凝聚或萃取,值得我们学习从而提高自己,开拓思路,更重要是转换思维角度。 其实,我们大多数人都活在“默认状态”下。没有发觉自己独特可设置选项-----思想。 言归正传(呵呵!恢复...

空空如也

空空如也

1 2 3
收藏数 57
精华内容 22
关键字:

思维思想思路的区别