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 对象是不可变的,所以可以共享) 字符串的本质是字符数组 ...
随机推荐
- pageadmin CMS网站制作教程:栏目单页内容如何修改
pageadmin CMS网站制作教程:栏目单页内容如何修改 一般情况下,如公司介绍,联系方式等介绍内页面都属于单页,单页内容可以直接在栏目设置界面进行修改,如下 1.对栏目单页内容进行设置,登录后台 ...
- python 设置默认的导包路径
在python中 可以通过 sys 模块添加导包时的搜寻路径, sys.path 返回的是所有默认导包路径的列表(搜索次序从下标为零开始,直到寻找到需要导入的包结束) sys.path.insert( ...
- django 获取外键对应数据的方式
模型 models.py中 from django.db import models class User(models.Model): name = models.CharField() class ...
- Memcached 查看列出所有key方法
Memcached没有一个比较简单的方法可以直接象Redis那样keys *列出所有的Session key,并根据key get对应的session内容,但是还是可以查看的 memcached 查看 ...
- #阿里云#云服务器部署Django(基础篇)
前言 本人能力有限,本文只是简单介绍基础部署流程,没有过多考虑系统安全等因素,请谅解.初学者参考了解,大神勿喷. 纯测试部署,采用阿里云ECS,系统Ubuntu 16.04 64位,部署采用nginx ...
- Kali Linux信息收集工具全集
001:0trace.tcptraceroute.traceroute 描述:进行路径枚举时,传统基于ICMP协议的探测工具经常会受到屏蔽,造成探测结果不够全面的问题.与此相对基于TCP协议的探测,则 ...
- OpenRefine导入CSV文件,数据清理后导出JSON格式
第一步:选择要转换的CSV文件. 第二步:选择以逗号分割,并创建项目. 第三步:编辑,去掉特殊字符 Edit Cells > Transform... 第四步:导出文件,选择“Templatin ...
- Storm原理及安装
http://my.oschina.net/leejun2005/blog/147607 http://www.storm-geek.com/forum.php http://www.zhangjih ...
- Netty核心概念(6)之Handler
1.前言 本节介绍Netty中第三个重要的概念——Handler,这个在前两节都提到了,尤其是Channel和Handler联系紧密.handler本身的设计非常简单,但是所起到的作用却很大,Nett ...
- certificate verify fails (https://gems.ruby-china.org错误
首先:执行这一步报错的背景是: 更换gems源, 通常执行 gem sources --add https://gems.ruby-china.org/ --remove https://rubyge ...