Java基础教程(10)--类

一.声明类

  你已经见过了以如下方式定义的类:

classMyClass{// field, constructor, and method declarations}

  上面是声明类的最基本的语法。可以在声明类时提供更多的信息,例如它继承的父类,或实现的接口等,例如:

classMyClassextendsMySuperClassimplementsMyInterface{// field, constructor, and method declarations}

这意味着MyClass类继承自MySuperClass类并是实现了MyInterface接口。

还可以在开头加上修饰符,例如public、private、final等。有关这些修饰符的作用将在下文中进行详细的介绍。一般来说,类声明由以下几部分组成:

修饰符。例如public、private以及其他将会在后面见到的修饰符;

类名。按照惯例使用首字母大写的驼峰命名法。

继承的父类。使用关键字extend声明,一个类只能直接继承一个父类。

一个或多个实现的接口。使用关键字implements声明,多个接口之间使用逗号隔开。

类体。定义在一对大括号中。

二.域的声明

  Bicycle类使用以下几行代码声明它的域:

publicintcadence;publicintgear;publicintspeed;

  域的声明由以下几部分组成:

修饰符,例如private、public、static、final等;

域的类型;

域的名称。

权限修饰符

  权限修饰符用来控制其他类对一个成员的访问权限。现在我们只讨论public和private,其他权限修饰符将在后面的文章中介绍。

public:可以从所有类访问该字段;

private:只能在自己的类中访问。

  本着封装的精神,应该尽可能地将域的访问权限设为private,这意味这只能在自己的类中访问它的值。但是,其他类仍有访问它的需要,可以通过添加访问域的方法来供其他类访问,就像下面这样:

publicclassBicycle{privateintcadence;privateintgear;privateintspeed;publicBicycle(intstartCadence,intstartSpeed,intstartGear){        gear = startGear;        cadence = startCadence;        speed = startSpeed;    }publicintgetCadence(){returncadence;    }publicvoidsetCadence(intnewValue){        cadence = newValue;    }publicintgetGear(){returngear;    }publicvoidsetGear(intnewValue){        gear = newValue;    }publicintgetSpeed(){returnspeed;    }publicvoidapplyBrake(intdecrement){        speed -= decrement;    }publicvoidspeedUp(intincrement){        speed += increment;    }}

三.定义方法

  下面定义了一个方法:

publicintadd(inta,intb){returna + b;}

  方法定义中必需的是返回值类型,方法名,一对小括号,以及大括号和方法体。更一般地来说,方法的声明由六个部分组成:

修饰符——例如public、private、static等;

返回值类型——方法返回的数据的类型。若方法无返回值则为void;

方法名称——和变量的命名规则相同,但惯例有一点不同;

参数列表——位于小括号中,用逗号隔开。方法也可以没有参数;

方法抛出的异常——有关这部分的内容将在后续教程中进行介绍;

方法体——位于大括号中,方法的具体代码。

签名:方法的签名由方法名称和参数列表组成。签名用来在一个类中唯一地标识一个方法,也就是说,一个类中不能存在两个签名相同的方法。上面的add方法的签名为add(int a, int b)。

  方法的名称可以是任何合法的标识符。但是按照惯例,方法名的第一个单词应该是动词并且小写它的首字母。例如run、compareTo等。

方法的重载

重载是指一个类中的两个或多个方法具有相同的名称但具有不同的参数列表。Java支持方法的重载,并且可以通过方法的签名区分它们。

假设有一个计算器类Calculator。为不同类型的操作数的加法设计不同的名字是一件很麻烦的事,例如addInt、addDouble、addFloat等。在Java中,可以为这些方法使用相同的名称,只要它们的参数列表是不同的。例如:

publicclassCalculator{publicstaticadd(inta,intb){returna + b;}publicstaticadd(doublea,doubleb){returna + b;}    ...}

  不能声明名称和参数列表都相同的方法,因为编译器无法区分它们。编译器在区分方法时只考虑签名,所以名称和参数列表相同,但返回值不同的两个方法并不算重载,编译器将会给出错误。

四.构造器

  构造器(也称构造方法)是将类实例化为对象是自动调用的方法。但与普通方法不同的是,它的名字与类名相同且没有返回值。例如,Bicycle类有一个构造方法:

publicBicycle(intstartCadence,intstartSpeed,intstartGear){    gear = startGear;    cadence = startCadence;    speed = startSpeed;}

  在创建对象时,new运算符将会调用构造方法:

Bicycle myBike =newBicycle(30,0,8);

  一个类可以有多个构造方法,只要它们的参数列表不同。还可以有无参构造方法:

publicBicycle(){    gear =1;    cadence =10;    speed =0;}

如果没有提供构造方法,编译器将会自动提供一个无参构造方法,这个无参构造方法会自动调用父类的无参构造方法。如果父类没有无参构造方法,编译器将会给出错误。因此在不提供构造方法时要保证父类有无参构造方法。如果你的类没有明确的父类,那么它有一个隐含的父类Object,这个类有一个无参构造方法。

可以在构造方法中手动调用父类的构造方法,有关这部分的内容将会在接口和继承的教程中介绍。还可以在构造方法的声明中使用访问修饰符来控制哪些类可以调用构造函数。如果某个类不能调用本类的构造方法,则无法在该类内部直接创建本类对象。

五.向方法或构造器传递参数

  方法的参数分为形式参数和实际参数。形式参数(简称形参)是方法声明中的参数列表,实际参数(简称实参)是指在调用方法时传递的具体的值。调用方法时,实际参数的顺序和类型必须与形式参数完全匹配。例如之前定义的add方法:

intadd(inta,intb){returna + b;}

  下面的语句调用了这个方法并把返回值赋值给变量sum,2和3就是调用方法时传递的实参:

intsum = add(2,3);

  还可以传递任意数量的参数。例如让add方法可以计算任意数量的整数的和:

intadd(int... a){intsum =0;for(inti =0; i < a.length; i++) {        sum += a[i];    }returnsum;}

可以看到,在方法内部,这个参数被视为一个数组,可以通过数组的访问形式去访问每一个参数。需要注意的是,参数列表中只能有一个这样的参数,并且它必须放在最后一个位置上。

形参的名称如果与类的某个域的名称相同,那么在这个方法内,这个形参将会屏蔽与它同名的域。可以使用this关键字来区分同名的形参和域,有关this关键字的内容将会在后面的文章中讨论。

基本数据类型参数

  基本数据类型的参数按值传递到方法中。这意味着对参数值的任何更改都仅存在于方法的范围内。方法返回时,参数消失,对它们的任何更改都将丢失。下面是一个例子:

publicclassPassPrimitiveByValue{publicstaticvoidmain(String[] args){inta =1;        increment(a);        System.out.println(a);    }publicstaticvoidincrement(intx){        x = x +1;    }}

  这个程序会输出1而不是2。x只是接收了a的值,对x的操作与a完全没有关系,所以函数结束后,a的值还是1。

引用类型参数

  引用类型的参数将引用传递到方法中。对形参的操作就相当于对实参进行同样的操作。例如:

publicclassPassPrimitiveByReference{publicstaticvoidmain(String[] args){        Foo foo =newFoo(1);        changeBar(foo);        System.out.println(foo.getBar());    }publicstaticvoidchangeBar(Foo f){        f.setBar(2);    }}classFoo{privateintbar;publicFoo(intbar){this.bar = bar;}publicintgetBar(){returnbar;}publicvoidsetBar(intbar){this.bar = bar;}}

  这个程序会输出2。因为形参f和实参foo引用了同一个对象。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,039评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,426评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,417评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,868评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,892评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,692评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,416评论 3 419
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,326评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,782评论 1 316
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,957评论 3 337
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,102评论 1 350
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,790评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,442评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,996评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,113评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,332评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,044评论 2 355

推荐阅读更多精彩内容