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 对象是不可变的,所以可以共享) 字符串的本质是字符数组 ...
随机推荐
- Eclipse (JavaEE版)中修改web项目的访问路径
访问路径,也就是指在浏览器中访问该web系统时的根路径,比如http://localhost:8080/xxxx/index.jsp 这里的xxxx. 也就是request.getContextPa ...
- MYsql 之单标查询.
http://www.cnblogs.com/wangfengming/articles/8064956.html .数据操作 .增 INSERT into t2(name,age) VALUES() ...
- day 94 RestFramework序列化组件与视图view
一 .复习 1. CBV流程 class BookView(View): def get(): pass def post(): pass #url(r'^books/', views.BookVie ...
- Mac OS 10.12 - 如何能够像在Windows一样切换中英文输入法和大小写键?
最开始,我切换中英文输入法和大小写键是按照下面博客做到的: http://www.cnblogs.com/sunylat/p/6415563.html 但是当我安装完毕搜狗输入法后,切换中英文输入法和 ...
- A - Subsequence (算法 二分 )
点击打开链接 A sequence of N positive integers (10 < N < 100 000), each of them less than or equal 1 ...
- Mac 切换到行首和行末的方法
苹果笔记本没有home键和end键 但是使用 command + 方向键左键可以回到行首, command + 方向键右键可以去到行末
- Good Bye 2017 G. New Year and Original Order
G. New Year and Original Order time limit per test 2 seconds memory limit per test 256 megabytes inp ...
- ActiveMQ使用线程池实现消息的生产与消费
jar文件:spring3.1jar,以及 项目src路径下文件:config.properties 读取config.properties文件JAVA类: package com.lejob.lej ...
- SQL 必知必会 总结(一)
SQL必知必会 总结(一) 第 1 课 了解SQL 1.数据库(database): 保存有组织的数据容器(通常是一个文件或一组文件). 2.数据库管理系统(DBMS): 数据库软件,数据库是通过 D ...
- JAVA并发编程学习笔记------多线程调优
1. 多线程场景下尽量使用并发容器代替同步容器 (如ConcurrentHashMap代替同步且基于散列的Map, 遍历操作为主要操作的情况下用CopyOnWriteArrayList代替同步的Lis ...