copyright © 2020 by 宇智波Akali
文章目录
第1章 Java基础语法
1、数据类型
1.1 八种基本数据类型
b y t e , s h o r t , i n t , l o n g , f l o a t , d o u b l e , c h a r , b o o l e a n byte, short, int, long, float, double, char, boolean byte,short,int,long,float,double,char,boolean
在Java中的关键字、保留字、标识符等使用方法和C++相似,但是变量:必须初始化。
byte类型的取值范围也是[-128, 127]。
long类型和float类型在定义时,值后面要加l或L, f或F。
long a = 3l; float b = 1.22F;
boolean类型不用0或非0的数值来表示,仅由 T r u e / F a l s e True/False True/False表示,这里和其他语言不同。
boolean b1 = true; boolean b2 = false;
换行输出语句:
System.out.println(str);
输入语句示例 e. g. 1-01:
//读入单个数据
Scenner scenner = new Scenner(System.in);
int input = scenner.nextInt(); //String input = scenner.next();
scenner.close();
//一次读入多个数据
Scenner scenner = new Scenner(System.in);
String str = scenner.nextLine(); //一次读入一行字符串
String strs[] = str.split(" "); //将上面的字符串按照空格划分为各个单位存在数组中
int a = Integer.parseInt(strs[0]);//通过基本类型的包装类将字符串转为基本数据类型
double b = Double.parseDouble(strs[1]);
1.2引用类型:String
String str = "Hello world!";
引用类型都可以用null作为值,也就是说可以在初始化的时候赋值为null,所以,String可以使用null作为值,此外,String与其他类型还有一个不同点:其值是不变的,这和引用类型在内存中的存储机制有关,后面会有涉及。
int i0 =1;
int i1 = 1;
//以上这种情况会在内存中存储2个1的值
String s0 = "Hello";
String s1 = "Hello";
//因为String是引用类型,所以只存在一个"Hello",变量名去引用"Hello".
String可以用加法进行拼接。
1.3基本数据类型转换
-
char, byte, short三者同级,不可互相转换且<int <long <float < double。
-
多种数据类型同时计算时,统一成最大容量的类型进行计算。
-
而多个相同类型变量运算时,先要转换为相对应的数据类型的默认类型(比如:两个byte类型的变量相加,会把两个byte类型转换为默认的int类型之后再计算,得到的结果是int类型)这种情况适用于变量类型的容量小于默认变量类型。
且:当把任何基本类型的值和字符串值进行连接运算时(+),基本数据类型自动转换为字符串类型。
1.3.1强制类型转换
e. g. int k = 7;
byte a = (byte) k;
//通常字符串不能直接转换为基本类型,但可以通过基本类型对应的包装类来实现:
String a = "43";
int i = Integer.parselnt(a);
boolean类型不可以转换为其他的数据类型。
2. 运算符
2.1赋值运算符
支持连续赋值。
思考1:
short s = 3;
s=s+2; ①
s+=2; ②
//①和②有什么区别?
①会报错,因为在运算s+2时会转换为int型,s != int型变量,这里应该手动强制类型转换:
s = (short) s + 2;
②可以正常运行,使用扩展赋值运算符时,会自动将变量类型强制转换为当前类型的变量类型。
思考2:
int i = 1;
i *= 0.1;
System.out.println(i);
// 输出 0,因为i = i * 0.1会强制转换为int型,0.1变成0
注意:
如果对负数取模,可以把模数负号忽略不记,如:5%-2=1。
但被模数是负数则不可忽略。此外,取模运算的结果不一定总是整数
int型之间做除法时,只保留整数部分而舍弃小数部分。
“+”除字符串相加功能外,还能把非字符串转换成字符串.例如:
System.out.println("5+5="+5+5); //打印结果是?5+5=55
以下二者的区别:
System.out.println(‘*’ + ‘\t’ +‘*’); 输出:93,为Ascall码,42+9+42=93 System.out.println(“*” + ‘\t’ +‘*’);输出:* *
2.2 逻辑运算符:与&、或|、非!、异或^
异或运算:一个true,一个false则为true 同为true或同为false则为false。
单&时,为逻辑与,左边无论真假,右边都进行运算。
双&时,为短路与,如果左边为真,右边参与运算,如果左边为假,那么右边不参与运算。
“|”和“||”的区别同理,||表示:当左边为真,右边不参与运算。
2.3其他运算符
- 位运算符:转换为2进制,各个位置进行运算。
- 三目运算符:(条件表达式)?表达式1:表达式2; 条件表达式为true则运算后的结果为表达式1否则为表达式2。
2.4 运算符优先级
略
3. 程序流程控制
3.1 顺序结构
按照顺序执行
3.2 分支结构
(1) if(条件){
语句;
}else if(条件){
语句;
}else{
语句;
}
(2) int i = 1;
switch(i){
case 1:
语句;
break;
case 2:
语句;
break;
default:
语句;
break;
}
//switch(表达式)中表达式的返回值必须是下述几种类型之一:byte, short, char, int, 枚举,String;
//case子句中的值必须是常量,且其值应该不同,语句块中没有break程序会执行到switch结尾
3.3 循环结构
- for 循环
- while 循环
- do-while 循环
- 循环嵌套
3.4 特殊流程控制语句
- break:结束当前所处的整个循环。
- continue:跳出当前循环,直接进去下一循环。
- return:并非专门用于结束循环,执行到return语句时,不管出于几层循环内,将结束整个方法。
4. 数组
数组为引用类型,分配空间时要new,传值时传递的是引用。
4.1 一维数组
声明方式:
//仅声明还不能使用,还要初始化,new分配空间。
type name[];
type[] name1;
数组声明以后在内存中没有分配具体的存储空间,也没有设定数组的长度。
初始化:
-
动态初始化:数组声明且为数组元素分配空间与赋值的操作分开进行。
int[] arr = new int[3]; //初始化时(声明时也可以用new)要传入数组长度;如果没有给数组元素赋值,则数组元素会默认初始化,数字类型默认为0,对象类型默认为null。 arr[0] = 3; arr[1] = 9; arr[2] = 8;
-
静态初始化:在定义数组的同时就为数组元素分配空间并赋值。
int a[] = new int[]{ 3, 9, 8}; int[] a = { 3,9,8};
4.2 多维数组
声明方式:·
int n[][];
初始化:
-
动态初始化
int a[][]; a = new int[2][3]; //或者声明和动态初始化同时进行 int n[][] = new int[2][3];//只声明,没有new分配空间和长度是无法使用的,一维数组也一样
-
静态初始化
int a[][] = new int [][]{ { 1,2}, { 2,2} };
-
让第二维长短不一
//如果需要初始化第二维长度不一样的二维数组,则可以使用如下的格式: int n[][]; n = new int[2][]; //只初始化第一维的长度 //分别初始化后续的元素 n[0] = new int[4]; n[1] = new int[3]; //得到 /*{ {1,2,3,4}, {2,3,4} }*/
5. 源文件布局
5.1 布局格式
[<包声明>]
[<引用声明>]
<类声明>
5.2 关键字-package
- package语句作为Java源文件的第一条语句,指明该文件中定义的类所在的包。若缺省该语句,则指定为无名包。
- 包对应于文件系统的目录,package语句中,用 “.” 来指明包(目录)的层次。
- 包通常用小写单词,类名首字母通常大写.
5.3 关键字-import
**作用:**为了使用定义在不同包中的Java类,需用import语句来引入指定包层次下所需要的类或全部类(.*),但是包内的子包中的类不会被引用。
语法格式:import 包名[.子包名…]. <类名 |*>
示例:
import p1.Test; //import p1.*;表示引入p1包中的所有类
public class TestPackage{
public static void main(String args[]){
Test t = new Test(); //Test类在p1包中定义
t.display();
}
}
import语句出现在package语句之后、类定义之前,一个源文件中可包含多个import语句。
第2章 Java 面向对象
1. 什么是面向对象
1.1 面向对象与面向过程
面向过程,强调的是功能行为;面向对象,将功能封装进对象,强调具备了功能的对象。
1.2 面向对象的三大特性
- 封装性
- 继承性
- 多态性
2. 类和对象
2.1类和对象的关系
类 = 汽车设计图 对象 = 实实在在的汽车
面向对象程序设计的重点是类的设计
定义类其实是定义类中的成员(成员变量和成员方法)
2.2 Java类及类的成员
Java的一个类class一般包含:
- 属性:即成员变量
- 行为:即成员方法(函数)
2.3 类的语法格式
修饰符 class 类名{
属性声明;
方法声明;
}
注意:方法中不能再定义方法
e. g. 2-01
public class Person {
//类的成员变量可以先声明,不用初始化,类成员变量是有默认值
public String name; //姓名,String的默认值是null
private int age; //年龄,int的默认值是0
public static String sex = "男"; //静态类变量-后面详解
/**
*行为,方法,也叫函数
*方法的名称如果是多个单词,首个的单词的首字母小写,其他的单词首字母大写,这样就像一个驼峰一样,所 *以叫驼峰命名法
*/
public void showName(){
System.out.println("姓名:" + name);
getAge(); //同一个类中,所有的方法可以直接互相调用,不用new去实例化对象
}
//有返回值的函数
public int getAge(){
return age;
}
}
2.4 类的实例化:对象的创建和使用
- 使用new + 类构造器创建一个新的对象
- 使用
对象名.对象成员
的方式访问对象成员(包括对象的属性和方法)
以e. g. 2-01中创建的Person类为例:
e. g. 2-02
public class People {
public static void main(String[] args){
//实例化Person类,也就是创建Person对象
Person person = new Person();
//声明一个Person类型的变量,变量名person,实例化Person类并且给person赋值,赋值的值就是当前的实例
person.name = "张三"; //给person对象的name属性赋值
person.showName(); //对象的方法的调用
int i = person.getAge();
System.out.println(i);
person.age = 11; //给person对象的age属性赋值
int a = person.getAge();
System.out.println(a);
}
}
//注:如果创建了一个类的多个对象,对于类中定义的属性,每个对象都拥有各自的一套副本,且互不干扰.
2.5 关于对象
2.51 匿名对象
- 概念: 不定义对象的句柄,而直接调用这个对象的方法,这样的对象叫做匿名对象。
- 使用情况: 如果对一个对象只需要进行一次方法调用,那么就可以使用匿名对象。 经常将匿名对象作为实参传递给一个方法调用。
e. g. 2-03
new Person().shout(); //没有给对象命名(定义句柄),直接调用对象中的方法。
2.5.2 在同一个类中的访问机制
类中的方法可以直接访问类中的成员变量。(例外:static方法访问非static的成员变量,编译不通过)
2.5.3 在不同类中的访问机制
先创建要访问类的对象,再用对象访问类中定义的成员。
3. 类的成员之一 :属性
3.1 语法格式
修饰符 类型 属性名 = 初值;
说明: 修饰符private:该属性只能由该类的方法访问,不能通过 对象.属性 的方式调用。
修饰符public:该属性可以被该类以外的方法访问。
类型:任何基本类型,如int、boolean或任何类。
3.2 变量分类
3.2.1 成员变量
-
实例变量(不以static修饰):
就是在类实例化成对象之后才能被使用的变量,如Person中的name(成员变量有默认的init值)。
实例变量存在于对象所在的堆内存中。 -
类变量(以static修饰):
这样的变量是静态的,类不需要实例化成对象就可以通过
类名.属性
调用.如Person中的sex。
3.2.2 局部变量
- 形参(方法签名中定义的变量)
- 方法局部变量(在方法内定义的变量)
- 代码块局部变量(在代码块中定义的变量)
注意:
a.局部变量存在于栈内存中,作用的范围结束,变量空间会自动释放.
b.局部变量没有默认初始化值,每次必须显式初始化.
c.局部变量声明时不指定权限修饰符,所以方法内的变量声明不用修饰符
4. 类的成员之二:方法
4.1 语法格式
修饰符 返回值类型 方法名(参数类型 形参1,参数类型 形参2,...){
程序代码
return 返回值;
}
说明: 修饰符:public, private, protected等。
返回类型为void,则不用return.关于形参,实参,返回值等不再记录,和C++完全一致
4.2 方法的注意事项
- 方法是类或对象行为特征的抽象,也称为函数
- Java里的方法不能独立存在,所有的方法必须定义在类里
- 方法只有被调用才会被执行
- 方法中只能调用方法,不可以在方法内部定义方法
并且在同一个类中,方法之间可以直接互相调用,所以在方法中调用另一个方法时不需new
4.3 方法的重载
4.3.1 概念
在同一个类中,允许存在一个以上的同名方法,只要它们的参数个数或者参数类型不同即可,与形参名无关。
4.3.2 重载代码示例
e. g. 2-04
public int add(int x, int y){
return x + y;
}
public double add(int x, double y){
return x + y;
}
public int add(int x, int y, int z){
return x + y + z;
}
//在主类Text中定义重载函数,在main()中,进行对象实例化,以及方法的调用
Text examp = new Text();
examp.add(1, 2);
examp.add(1, 0.5);
examp.add(1,2,3);
4.3.3 方法重载的特点
- 与返回值类型无关,只看参数列表,且参数列表必须不同。
- 参数个数或参数类型,参数相同只是顺序不同也可以构成重载,调用时,根据方法参数列表的不同来区别。
4.4 方法之可变个数的形参
4.4.1 定义方法
- a.使用数组作为形参
传参使用时需要在main函数中new一个数组作为实参传入,数组长度可为 0 → + ∞ 0 \to+ \infty 0→+∞
public void printInfo(String[] args){
//这里的String可以根据需要使用基本数据类型
for(int i = 0; i < args.length; i++){
System.out.println(args[i]);
}
}
- b.使用Java自带的可变形参表示法
(使用方法与使用数组的形式相同)
e. g. 2-05:
//方法的参数部分有可变形参,需要放在形参声明的最后
public void printInfo1(int d, String... args){
for(int i = 0; i < args.length; i++){
System.out.println(args[i]);
}
}
//使用:(在此之前要在main中实例化一个方法所在的类,命名为p3)
p3.printInfo1(2,"lisi", "23", "男");
//或者像使用数组一样
String[] ss2 = new String[]{
"北京市xxx","13133334444","152109874523666541"};
p3.printInfo1(ss2);
//不同的是,当参数为空时,使用数组的方法要传入null或空数组,用b方法形参可以空着
4.5 JVM的内存模型图
4.6 方法的参数传递
-
Java里方法的参数传递方式只有一种:值传递
即将实际参数值的副本(复制品)传入方法内,而参数本身不受影响。
-
参数传递的两种情况:
- a.如果方法的形参是基本数据类型,那么实参(实际的数据)向形参传递参数时,就是直接传递值,把实参的值复制给形参。
- b.如果方法的形参是对象,那么实参(实际的对象),向形参传递参数的时,也是把值给形参,这个值是实参在栈内存中的值,也就是引用对象在堆内存中的地址。
- 基本数据类型都是保存在栈内存中,引用对象在栈内存中保存的是引用对象的地址,那么方法的参数传递是传递值(是变量在栈内存的当中的值)
-
参数传递的内存示意图:
5.类的成员之三:构造器
5.1 语法格式
修饰符 类名 (参数列表) {
//修饰符与类的修饰符一致
初始化语句; //可以使用初始化语句和参数列表将类的属性默认初始化或显式初始化
}
5.2 构造器的特征
- 它具有与类相同的名称
- 它不声明返回值类型。(与声明为void不同)
- 不能被static、final、synchronized、abstract、native修饰,不能有return语句返回值
5.3 构造器的作用
创建对象,以及给对象进行初始化。
比如:Order o = new Order();
Person p = new Person(Peter,15);
new对象 实际就是调用类的构造器(C++中的构造方法、构造函数在Java中称构造器)。
5.4 构造器的分类
根据参数不同构造器可以分为如下两类:
- 隐式无参构造器(系统默认提供)
- 显式定义一个或多个构造器(无参或有参)
注意:
a. Java语言中,每个类都至少有一个构造器
b. 默认构造器的修饰符与所属类的修饰符一致
c. 一旦显式定义了构造器,则系统不再提供默认构造器
d. 一个类可以创建多个重载的构造器
e. 父类的构造器不可被子类继承
5.5 构造器重载
构造器的重载使得对象的创建更加灵活,方便创建各种不同的对象。
e. g. 2-06 :
public class Person{
//构造器重载,参数列表必须不同
public Person(String name, int age, Date d) {
this(name,age);…}
public Person(String name, int age) {
…}
public Person(String name, Date d) {
…}
public Person(){
…}
}
6. 类的成员之四:初始化块(代码块)
01. 作用: 对Java对象进行初始化。
**02. 程序的执行顺序:**声明成员变量的默认值 -> 静态代码块 -> 显式初始化、多个初始化块依次被执行(同级别下按先后顺序执行) -> 构造器再对成员进行赋值操作
**03. 静态代码块:**一个类中初始化块若有修饰符,则只能被static修饰,称为静态代码块(static block ),当类被载入时,类属性的声明和静态代码块先后顺序被执行,且只被执行一次。
04. static块通常用于初始化static (类)属性
示例:e. g. 2-07:
class Person {
public static int total;
static {
total = 100;//为total赋初值
}
…… //其它属性或方法声明
}
05. 非静态代码块:没有static修饰的代码块
a. 可以有输出语句。
b. 可以对类的属性声明进行初始化操作。
c. 可以调用静态和非静态的变量或方法。
d. 若有多个非静态的代码块,那么按照从上到下的顺序依次执行。
e. 每次创建对象的时候,都会执行一次,且先于构造器执行。
06. 静态代码块:用static 修饰的代码块
a. 可以有输出语句。
b. 可以对类的属性声明进行初始化操作。
c. 不可以对非静态的属性初始化。即:不可以调用非静态的属性和方法。
d. 若有多个静态的代码块,那么按照从上到下的顺序依次执行。
e. 静态代码块的执行要先于非静态代码块。
f. 静态代码块只执行一次。
7. 类的成员之五: 内部类
概念: 在Java中,允许一个类的定义位于另一个类的内部,前者称为内部类,后者称为外部类。
作用: 解决Java不能多重继承的问题(接口也可以),有时只有一个方法想要继承,专门写一个接口显得有点繁琐,可以在类中写一个内部类,用内部类继承该类的方法即可。
a. 内部类可以使用外部类的私有数据,因为它是外部类的成员,同一个类的成员之间可相互访问。而外部类要访问内部类中的成员需要 内部类.成员
或者 内部类对象.成员
。
b. 内部类可以声明为static,但此时就不能再使用外层类的非static的成员变量。非static的内部类中的成员不能声明为static的,只有在外部类或static的内部类中才可声明static成员
c. 内部类可以声明为abstract类型或final类型 ,因此可以被其它的内部类继承或者终止继承。
代码示例: e. g. 2-08
class A {
private int s;
public class B{
//定义内部类
public void mb() {
s = 100;
System.out.println("在内部类B中s=" + s);
} }
public void ma() {
//定义在外部类中访问内部类的方法
B i = new B();
i.mb();
}
}
public class Test {
public static void main(String args[]){
A o = new A();
o.ma(); //创建外部类对象,通过外部类中的方法访问内部类
}
}
第3章 面向对象的特征
1. 面向对象的特征之一: 封装和隐藏
使用者对类内部定义的属性(对象的成员变量)的直接操作会导致数据的错误、混乱或安全性问题,因此需要对类进行封装和隐藏。
- Java中通过将数据声明为私有的(private),再提供公共的(public)方法get_X()和set_X()等方法,实现对该属性的操作,以实现下述目的:
a. 隐藏一个类中不需要对外提供的实现细节;
b. 使用者只能通过事先定制好的方法来访问数据,可以方便地加入控制逻辑,限制对属性的不合理操作;
c. 便于修改,增强代码的可维护性;
- 四种访问权限修饰符
- 注意:
a. 对于class的权限修饰只可以用public和default(缺省)。
b. public类可以在任意地方被访问。
c. default类只可以被同一个包内部的类访问。
d. 在同一个Java文件中可以写多个class,但是只有一个可以定义为public,其他修饰符空着(default)
2. 面向对象的特征之二: 继 承
多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么子类无需再定义这些属性和行为,只要继承父类即可,比如 Person类中的属性和行为在 Student、Teacher等类中也有,后者只需要继承前者即可拥有Person的所有属性、行为。
2.1 定义方法
//定义父类
public class Person {
public String name;
public int age;
public String getInfo() {
...}
}
//使用extends关键字定义继承的子类,意即对父类的"扩展".
public class Student extends Person{
public String school;
}
//Student类继承了父类Person的所有属性和方法,并增加了一个属性school.
//Person中的属性和方法,Student都可以利用.
//如果子类和父类不在同一个包下,子类只能使用父类中public和protected修饰的成员
继承的出现提高了代码的复用性。
继承的出现让类与类之间产生了关系,提供了多态的前提。
不要仅为了获取其他类中某个功能而去继承,继承的类之间应该有逻辑性
子类不能直接访问父类中私有的(private)的成员变量和方法,应通过setter、getter方法访问
注意: 一个子类只能有一个父类,一个父类可以派生出多个子类,Java支持多层继承,但不支持一个子类多个父类这样的多重继承。
2.2 方法的重写(override)
(1)概念:在子类中可以根据需要对从父类中继承来的方法进行改造,子类的方法将覆盖父类的方法,称重写。
(2)示例:
e. g. 2-07:
public class Person {
public String name;
public int age;
public String getInfo() {
return "Name: "+ name + "\n" +"age: "+ age;
}
}
public class Student extends Person {
public String school;
public String getInfo() {
//重写方法
return "Name: "+ name + "\nage: "+ age
+ "\nschool: "+ school;
}
}
(3)方法重写时的注意:
a. 重写方法必须和被重写方法具有相同的方法名称、参数列表和返回值类型。
b. 重写方法不能使用比被重写方法更严格的访问权限。
c. 重写和被重写的方法须同时为static的,或同时为非static的。
d. 子类方法抛出的异常不能大于父类被重写方法的异常
在eclipse中可以使用快捷键 Alt+/ 选择override进行快速重写。
3. 面向对象的特征之三:多态性
3.1 Java中多态性的两种体现
-
方法的重载(overload)和重写(overwrite)
**a. 重载:**本类中允许同名方法存在,体现相同的方法实现不同的逻辑。
b. 重写: 子类对父类方法的覆盖,子类可以使用和父类相同的方法名,覆盖掉父类的逻辑。
-
**对象的多态性:**子类的对象可以替代父类的对象使用,可以直接应用在抽象类和接口上。
-
Java引用变量有两个类型:
编译时类型和运行时类型。编译时类型由声明该变量时使用的类型决定,运行时类型由实际赋给该变量的对象决定。若编译时类型和运行时类型不一致,就出现多态(Polymorphism)。
3.2 对象的多态性
-
一个变量只能有一种确定的数据类型,但一个引用类型变量可能指向(引用)多种不同类型的对象,例如:
Person p = new Person(); Person e = new Student(); // Person类型的变量e,指向Student类型的对象
-
子类可看做是特殊的父类,所以父类类型的引用可以指向子类的对象:向上转型(up-casting)。即子类的对象可以给父类类型的变量作为引用。
-
一个引用类型变量如果声明为父类的类型,但实际引用的是子类对象,那么该变量就不能再访问子类中添加的属性和方法。例如:
Student m = new Student(); m.school = “BNU”; //合法,Student类有school成员变量 Person e = new Student(); e.school = “BNU”; //非法,Person类没有school成员变量 //属性是在编译时确定的,编译时e为Person类型,没有school成员变量,因而编译错误。
-
虚拟方法调用
//正常的方法调用
Person p = new Person();
p.getInfo();
Student s = new Student();
s.getInfo();
//虚拟方法调用(多态情况下)
Person e = new Student();
e.getInfo(); //调用Student类的getInfo()方法
//编译时类型和运行时类型,编译时e为Person类型,而方法的调用是在运行时确定的,所以调用的是Student类的getInfo()方法。
//Java的方法是运行在栈内存中的,在运行方法时会动态进栈和出栈--动态绑定.
多态小结:
前提:
a. 需要存在继承或者实现关系
b. 要有覆盖操作
成员方法:
编译时:要查看引用变量所属的类中是否有所调用的方法.
运行时:调用实际对象所属的类中的重写方法.
成员方法的多态性,也就是多态绑定,必须在有方法的重写前提下才能进行.
成员变量:
不具备多态性,只看引用变量所属的类.
第4章 高级类特性01
1. 关键字-this
作用:
01. 它在方法内部使用,即表示这个方法所属对象的引用;
2. 它在构造器内部使用,表示该构造器正在初始化的对象;
3. this表示当前对象,可以调用类的属性、方法和构造器;
使用时机: 当在方法内需要用到调用该方法的对象时,就用this。
使用this调用属性方法代码示例: e. g. 4-01:
/**
* a.当形参与成员变量重名时,如果在方法内部需要使用成员变量,
* 必须添加this来表明该变量时类成员
* b.在任意方法内,如果使用当前类的成员变量或成员方法可以在其前面添加this,
* 增强程序的阅读性
*/
class Person{
// 定义Person类
private String name ;
private int age ;
public Person(String name,int age){
this.name = name ; //这里必须用this指针表明name为类的属性,而非形参
this.age = age ; }
public void getInfo(){
System.out.println("姓名:" + name) ;
this.speak();
}
public void speak(){
System.out.println(“年龄:” + this.age);
}
}
class Person{
// 定义Person类
private String name ;
private int age ;
public Person(){
// 无参构造
System.out.println("新对象实例化") ;
}
public Person(String name){
this(); // 调用本类中的无参构造方法,且放在构造方法的首行
this.name = name ;
}
public Person(String name,int age){
this(name) ; // 调用有一个参数的构造方法,且放在构造方法的首行
this.age = age;
}
public String getInfo(){
return "姓名:" + name + ",年龄:" + age ;
}
}
/**
* c.this可以作为一个类中,构造器相互调用的特殊格式
* d.使用this()必须放在构造器的首行
* e.使用this调用本类中其他的构造器,保证至少有一个构造器是不用this的。
*(实际上就是不能出现构造器自己调用自己)
*/
2. 关键字-super
作用:
- super可用于访问父类中定义的属性,方法,以及父类的构造函数。
- a. 尤其当子父类出现同名成员时,可以用super进行区。
b. super的追溯不仅限于直接父类,还可以调用子类之上的所有父类。
c. super和this的用法相像,this代表本类对象的引用,super代表父类的内存空间的标识。
使用方法: 使用 super.+父类成员 进行调用。
注意:
a.子类中所有的构造器默认都会访问父类中空参数的构造器
b.当父类中没有空参数的构造器时,子类的构造器必须通过this(参数列表)或者super(参数列表)语句指定调用本类或者父类中相应的构造器,且必须放在构造器的第一行
c.如果子类构造器中既未显式调用父类或本类的构造器,且父类中又没有无参的构造器,则编译出错
代码示例: e. g. 4-02:
//定义父类
public class Person {
private String name;
private int age;
private Date birthDate;
public Person(String name, int age, Date d) {
this.name = name;
this.age = age;
this.birthDate = d;
}
public Person(String name, int age) {
this(name, age, null);
}
public Person(String name, Date d) {
this(name, 30, d);
}
public Person(String name) {
this(name, 30);
}
}
//调用父类
public class Student extends Person {
private String school;
public Student(String name, int age, String s) {
super(name, age);
school = s;
}
public Student(String name, String s) {
super(name);
school = s;
}
public Student(String s) {
// 编译出错: no super(),系统将调用父类无参数的构造方法。
school = s;
}
}
3. this和super的区别
4. JavaBean
概念: JavaBean 是一种Java语言写成的可重用组件。所谓 JavaBean,是指符合如下标准的Java类:
a. 类是公共的;
b. 有一个无参的公共的构造器;
c. 有属性,属性一般是私有的,且有对应的get、set方法;
用户可以认为JavaBean提供了一种随时随地的复制和粘贴的功能,而不用关心任何改变。
对于eclipse,在创建了类和其中的属性后,可以使用 右键 -> Source -> Generate Getters and Setters.
5. instanceof操作符
作用:x instanceof A
检验x是否为类A的对象,返回值为boolean型。
要求x所属的类与类A必须是子类和父类的关系,否则编译错误。
如果x属于类A的子类B,x instanceof A
值也为true。
6. Object类
概念: Object类是所有Java类的根父类(基类)。在多层继承中处于最高层的父类一定是Object类。
如果在类的声明中未使用extends关键字指明其父类,则默认父类为Object类 :
示例: e. g. 4-03:
public class Person {
...
}
//等价于:
public class Person extends Object {
...
}
**作用:**可以用于接收作为参数的类。
示例:e. g. 4-04:
method(Object obj)