Java基础教程(10)--类
一.声明类
你已经见过了以如下方式定义的类:
class MyClass {
// field, constructor, and method declarations
}
上面是声明类的最基本的语法。可以在声明类时提供更多的信息,例如它继承的父类,或实现的接口等,例如:
class MyClass extends MySuperClass implements MyInterface {
// field, constructor, and method declarations
}
这意味着MyClass类继承自MySuperClass类并是实现了MyInterface接口。
还可以在开头加上修饰符,例如public、private、final等。有关这些修饰符的作用将在下文中进行详细的介绍。一般来说,类声明由以下几部分组成:
- 修饰符。例如public、private以及其他将会在后面见到的修饰符;
- 类名。按照惯例使用首字母大写的驼峰命名法。
- 继承的父类。使用关键字extend声明,一个类只能直接继承一个父类。
- 一个或多个实现的接口。使用关键字implements声明,多个接口之间使用逗号隔开。
- 类体。定义在一对大括号中。
二.域的声明
Bicycle类使用以下几行代码声明它的域:
public int cadence;
public int gear;
public int speed;
域的声明由以下几部分组成:
- 修饰符,例如private、public、static、final等;
- 域的类型;
- 域的名称。
权限修饰符
权限修饰符用来控制其他类对一个成员的访问权限。现在我们只讨论public和private,其他权限修饰符将在后面的文章中介绍。
- public:可以从所有类访问该字段;
- private:只能在自己的类中访问。
本着封装的精神,应该尽可能地将域的访问权限设为private,这意味这只能在自己的类中访问它的值。但是,其他类仍有访问它的需要,可以通过添加访问域的方法来供其他类访问,就像下面这样:
public class Bicycle {
private int cadence;
private int gear;
private int speed;
public Bicycle(int startCadence, int startSpeed, int startGear) {
gear = startGear;
cadence = startCadence;
speed = startSpeed;
}
public int getCadence() {
return cadence;
}
public void setCadence(int newValue) {
cadence = newValue;
}
public int getGear() {
return gear;
}
public void setGear(int newValue) {
gear = newValue;
}
public int getSpeed() {
return speed;
}
public void applyBrake(int decrement) {
speed -= decrement;
}
public void speedUp(int increment) {
speed += increment;
}
}
三.定义方法
下面定义了一个方法:
public int add(int a, int b) {
return a + b;
}
方法定义中必需的是返回值类型,方法名,一对小括号,以及大括号和方法体。更一般地来说,方法的声明由六个部分组成:
- 修饰符——例如public、private、static等;
- 返回值类型——方法返回的数据的类型。若方法无返回值则为void;
- 方法名称——和变量的命名规则相同,但惯例有一点不同;
- 参数列表——位于小括号中,用逗号隔开。方法也可以没有参数;
- 方法抛出的异常——有关这部分的内容将在后续教程中进行介绍;
- 方法体——位于大括号中,方法的具体代码。
签名:方法的签名由方法名称和参数列表组成。签名用来在一个类中唯一地标识一个方法,也就是说,一个类中不能存在两个签名相同的方法。上面的add方法的签名为add(int a, int b)。
方法的名称可以是任何合法的标识符。但是按照惯例,方法名的第一个单词应该是动词并且小写它的首字母。例如run、compareTo等。
方法的重载
重载是指一个类中的两个或多个方法具有相同的名称但具有不同的参数列表。Java支持方法的重载,并且可以通过方法的签名区分它们。
假设有一个计算器类Calculator。为不同类型的操作数的加法设计不同的名字是一件很麻烦的事,例如addInt、addDouble、addFloat等。在Java中,可以为这些方法使用相同的名称,只要它们的参数列表是不同的。例如:
public class Calculator {
public static add(int a, int b) {return a + b;}
public static add(double a, double b) {return a + b;}
...
}
不能声明名称和参数列表都相同的方法,因为编译器无法区分它们。编译器在区分方法时只考虑签名,所以名称和参数列表相同,但返回值不同的两个方法并不算重载,编译器将会给出错误。
四.构造器
构造器(也称构造方法)是将类实例化为对象是自动调用的方法。但与普通方法不同的是,它的名字与类名相同且没有返回值。例如,Bicycle类有一个构造方法:
public Bicycle(int startCadence, int startSpeed, int startGear) {
gear = startGear;
cadence = startCadence;
speed = startSpeed;
}
在创建对象时,new运算符将会调用构造方法:
Bicycle myBike = new Bicycle(30, 0, 8);
一个类可以有多个构造方法,只要它们的参数列表不同。还可以有无参构造方法:
public Bicycle() {
gear = 1;
cadence = 10;
speed = 0;
}
如果没有提供构造方法,编译器将会自动提供一个无参构造方法,这个无参构造方法会自动调用父类的无参构造方法。如果父类没有无参构造方法,编译器将会给出错误。因此在不提供构造方法时要保证父类有无参构造方法。如果你的类没有明确的父类,那么它有一个隐含的父类Object,这个类有一个无参构造方法。
可以在构造方法中手动调用父类的构造方法,有关这部分的内容将会在接口和继承的教程中介绍。还可以在构造方法的声明中使用访问修饰符来控制哪些类可以调用构造函数。如果某个类不能调用本类的构造方法,则无法在该类内部直接创建本类对象。
五.向方法或构造器传递参数
方法的参数分为形式参数和实际参数。形式参数(简称形参)是方法声明中的参数列表,实际参数(简称实参)是指在调用方法时传递的具体的值。调用方法时,实际参数的顺序和类型必须与形式参数完全匹配。例如之前定义的add方法:
int add(int a, int b) {
return a + b;
}
下面的语句调用了这个方法并把返回值赋值给变量sum,2和3就是调用方法时传递的实参:
int sum = add(2, 3);
还可以传递任意数量的参数。例如让add方法可以计算任意数量的整数的和:
int add(int... a) {
int sum = 0;
for(int i = 0; i < a.length; i++) {
sum += a[i];
}
return sum;
}
可以看到,在方法内部,这个参数被视为一个数组,可以通过数组的访问形式去访问每一个参数。需要注意的是,参数列表中只能有一个这样的参数,并且它必须放在最后一个位置上。
形参的名称如果与类的某个域的名称相同,那么在这个方法内,这个形参将会屏蔽与它同名的域。可以使用this关键字来区分同名的形参和域,有关this关键字的内容将会在后面的文章中讨论。
基本数据类型参数
基本数据类型的参数按值传递到方法中。这意味着对参数值的任何更改都仅存在于方法的范围内。方法返回时,参数消失,对它们的任何更改都将丢失。下面是一个例子:
public class PassPrimitiveByValue {
public static void main(String[] args) {
int a = 1;
increment(a);
System.out.println(a);
}
public static void increment(int x) {
x = x + 1;
}
}
这个程序会输出1而不是2。x只是接收了a的值,对x的操作与a完全没有关系,所以函数结束后,a的值还是1。
引用类型参数
引用类型的参数将引用传递到方法中。对形参的操作就相当于对实参进行同样的操作。例如:
public class PassPrimitiveByReference {
public static void main(String[] args) {
Foo foo = new Foo(1);
changeBar(foo);
System.out.println(foo.getBar());
}
public static void changeBar(Foo f) {
f.setBar(2);
}
}
class Foo {
private int bar;
public Foo(int bar) {this.bar = bar;}
public int getBar() {return bar;}
public void setBar(int bar) {this.bar = bar;}
}
这个程序会输出2。因为形参f和实参foo引用了同一个对象。
Java基础教程(10)--类的更多相关文章
- Java基础教程——BigDecimal类
BigDecimal类 float.double类型的数字在计算的时候,容易发生精度丢失. 使用java.math.BigDecimal类可以解决此类问题. 前面讲过Math类,现在的BigDecim ...
- Java基础教程——Date类和Calendar类
Date类和Calendar类都是关于日期的类,都在java.util包中,使用时需要import. Date java.util.Date类的对象用来表示时间和日期,用得最多的是获取系统当前日期和时 ...
- Java基础教程——Math类
Math Java这种级别的编程语言怎么可能没有数学相关的操作呢? java.lang.Math类提供了基本数学运算的方法. 该类是final的,说明不能被继承. 该类的构造方法是私有的(privat ...
- Java基础教程——File类、Paths类、Files类
File类 File类在java.io包中.io代表input和output,输入和输出. 代表与平台无关的文件和目录. 可以新建.删除.重命名,但不能访问文件内容. File类里的常量: impor ...
- Java基础教程——Scanner类
Scanner属于java.util包. java.util包是Java内置的一个工具包,其中包含一系列常用的工具类,如处理日期.日历.集合类: 如果要使用到该包中的类,必须显式引入包名:import ...
- Java基础教程——RunTime类
RunTime类 java.lang.RunTime类代表Java程序的运行时环境. 可以进行垃圾回收(gc()),可以进行系统资源清理(runFinalization()): 可以加载文件(load ...
- Java基础教程——System类
System类 java.lang.System类代表当前Java程序的运行平台. |-可以做输入输出,垃圾回收:(此处不讲) |-可以获取时间: |-可以获取环境变量: |-可以获取系统信息: |- ...
- Java基础教程——Object类
Object类 Object类是Java所有类类型的父类(或者说祖先类更合适) <Thinking in Java(Java编程思想)>的第一章名字就叫"everything i ...
- Java基础教程——String类
String类 Java程序中的所有字符串字面值(如 "abc" )都是String的实例 字符串是常量(因为 String 对象是不可变的,所以可以共享) 字符串的本质是字符数组 ...
随机推荐
- Unity获取object所有属性的一个方法,一些界面上没有开放的属性可以用该方法编辑
static void PrintProperty () { if(Selection.activeObject == null) return; SerializedObject so = new ...
- 基于JMS的ActiveMQ搭建与实现
1.JMS Java消息服务(Java Message Service)即JMS,是一个Java平台中关于面向消息中间件的API,用于两个程序之间,或分布式系统中发送消息,进行异步通信. JMS包括队 ...
- CentOS 7 - 安装Eclipse
注意问题:Eclipse官方网站提供的tar文件有可能有问题,我今天下载的一个tar文件,在Windows下解压缩,随后放到CentOS 7里面不行,随后我又重新下载一份,还是不行,最终我下载了另外一 ...
- 内存耗用:VSS/RSS/PSS/USS
Terms VSS - Virtual Set Size 虚拟耗用内存(包含共享库占用的内存) RSS - Resident Set Size 实际使用物理内存(包含共享库占用的内存) PSS - P ...
- BZOJ 5395--[Ynoi2016]谁的梦(STL&容斥)
5395: [Ynoi2016]谁的梦 Time Limit: 80 Sec Memory Limit: 128 MBSubmit: 22 Solved: 7[Submit][Status][Di ...
- 七,mysql优化——表的垂直划分和水平划分
1,表的水平划分 如果一个表的记录数太多,比如成千上万条,而且需要经常检索,那么我们有必要化整为零.如果我拆成100个表,那么每个表只有10万条记录.当然需要数据在逻辑上可以划分.一个好的划分依据,有 ...
- Android之开源项目汇总
汇总一:http://www.trinea.cn/android/android-open-source-projects-view/ 汇总二:http://blog.csdn.net/liuhaom ...
- Python 去除列表中重复的元素
Python 去除列表中重复的元素 来自比较容易记忆的是用内置的set l1 = ['b','c','d','b','c','a','a'] l2 = list(set(l1)) print l2 还 ...
- Android Ble4.0开发
最近在做一个蓝牙的项目,是Blu4.0,Android系统支持是4.3版本以上(为此特地卖了个手机,). 当然也参考了不少大牛的的微博,说的都不错,再次特地感谢 http://blog.csdn.ne ...
- P1631 序列合并
P1631 序列合并 有两个长度都是N的序列A和B,在A和B中各取一个数相加可以得到N^2N2个和,求这N^2N2个和中最小的N个. 对于100%的数据中,满足1<=N<=100000. ...