Java学习日志7

First Post:

Last Update:

Word Count:
2k

Read Time:
8 min

this关键字

1.1、this是一个关键字,是一个引用,保存内存地址指向自身。
1.2、this可以使用在实例方法中,也可以使用在构造方法中。
1.3、this出现在实例方法中其实代表的是当前对象
1.4、this不能使用在静态方法中
1.5、this. 大部分情况下可以省略,但是用来区分局部变量和实例变量的时候不能省略。
1.6、this() 这种语法只能出现在构造方法第一行,表示当前构造方法调用本类其他的构造方法,目的是代码复用。

JVM中的体现

015this关键字.png

代码示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
/*
1、this可以使用在实例方法中,不能使用在静态方法中。
2、this关键字大部分情况下可以省略,什么时候不能省略呢?
在实例方法中,或者构造方法中,为了区分局部变量和实例变量,
这种情况下:this. 是不能省略的。
*/
public class ThisTest03{
public static void main(String[] args){

Student s = new Student();
s.setNo(111);
s.setName("张三");
System.out.println("学号:" + s.getNo());
System.out.println("姓名:" + s.getName());

Student s2 = new Student(2222, "李四");
System.out.println("学号:" + s2.getNo());
System.out.println("姓名:" + s2.getName());

}
}

// 分析一下:以下代码哪里写的不好。
// 学生类
class Student{
//学号
private int no;

//姓名
private String name;

//构造方法无参
public Student(){

}

//构造方法有参
/*
public Student(int i, String s){
no = i;
name = s;
}
*/

// 上面的构造方法也增强以下可读性
public Student(int no, String name){
this.no = no;
this.name = name;
}

// setter and getter方法
/*
public void setNo(int i){
no = i;
}
*/
/*
public void setNo(int no){ // 就近原则。
no = no; //这两个no都是局部变量no,和实例变量no没关系。
}
*/
public void setNo(int no){
//no是局部变量
//this.no 是指的实例变量。
this.no = no; // this. 的作用是:区分局部变量和实例变量。
}
public int getNo(){
return no;
//return this.no;
}
/*
public void setName(String s){
name = s;
}
*/
/*
public void setName(String name){ // 就近原则
name = name; //这两个name都是局部变量name,和实例变量name没关系。
}
*/
public void setName(String name){
this.name = name;
}

/*
public String getName(){
return name;
}
*/

public String getName(){ // getName实际上获取的是“当前对象”的名字。
//return this.name; // 严格来说,这里是有一个 this. 的。只不过这个 this. 是可以省略的。
return name;
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
/*
1、this除了可以使用在实例方法中,还可以用在构造方法中。
2、新语法:通过当前的构造方法去调用另一个本类的构造方法,可以使用以下语法格式:
this(实际参数列表);
通过一个构造方法1去调用构造方法2,可以做到代码复用。
但需要注意的是:“构造方法1”和“构造方法2” 都是在同一个类当中。

3、this() 这个语法作用是什么?
代码复用。

4、死记硬背:
对于this()的调用只能出现在构造方法的第一行。
*/
public class ThisTest04{
public static void main(String[] args){
// 调用无参数构造方法
Date d1 = new Date();
d1.detail();

// 调用有参数构造方法
Date d2 = new Date(2008, 8, 8);
d2.detail();
}
}

/*
需求:
1、定义一个日期类,可以表示年月日信息。
2、需求中要求:
如果调用无参数构造方法,默认创建的日期为:1970年1月1日。
当然,除了调用无参数构造方法之外,也可以调用有参数的构造方法来创建日期对象。
*/
class Date{ // 以后写代码都要封装,属性私有化,对外提供setter and getter
//年
private int year;
//月
private int month;
//日
private int day;

// 构造方法无参
// 调用无参数构造方法,初始化的日期是固定值。
public Date(){
//错误: 对this的调用必须是构造器中的第一个语句
//System.out.println(11);
/*
this.year = 1970;
this.month = 1;
this.day = 1;
*/
this(1970, 1, 1);
}
// 构造方法有参数
public Date(int year, int month, int day){
this.year = year;
this.month = month;
this.day = day;
}

// 提供一个可以打印日期的方法
public void detail(){
//System.out.println(year + "年" + month + "月" + day + "日");
System.out.println(this.year + "年" + this.month + "月" + this.day + "日");
}

//setter and getter
public void setYear(int year){
// 设立关卡(有时间可以设立关卡)
this.year = year;
}
public int getYear(){
return year;
}
public void setMonth(int month){
// 设立关卡(有时间可以设立关卡)
this.month = month;
}
public int getMonth(){
return month;
}
public void setDay(int day){
// 设立关卡(有时间可以设立关卡)
this.day = day;
}
public int getDay(){
return day;
}
}


继承(上)

1、什么是继承,有什么用?
继承:在现实世界当中也是存在的,例如:父亲很有钱,儿子不用努力也很有钱。
继承的作用:
基本作用:子类继承父类,代码可以得到复用。(这个不是重要的作用,是基本作用。)
主要(重要)作用:因为有了继承关系,才有了后期的方法覆盖多态机制

2、继承的相关特性
① B类继承A类,则称A类为超类(superclass)、父类、基类,
B类则称为子类(subclass)、派生类、扩展类。
class A{}
class B extends A{}
我们平时聊天说的比较多的是:父类和子类。
superclass 父类
subclass 子类

② java 中的继承只支持单继承,不支持多继承,C++中支持多继承,
这也是 java 体现简单性的一点,换句话说,java 中不允许这样写代码:
class B extends A,C{ } 这是错误的。

③ 虽然 java 中不支持多继承,但有的时候会产生间接继承的效果,
例如:class C extends B,class B extends A,也就是说,C 直接继承 B,
其实 C 还间接继承 A。

④ java 中规定,子类继承父类,除构造方法不能继承之外,剩下都可以继承。但是私有的属性无法在子类中直接访问。(父类中private修饰的不能在子类中直接访问。可以通过间接的手段来访问。)

⑤ java 中的类没有显示的继承任何类,则默认继承 Object类,Object类是
java 语言提供的根类(老祖宗类),也就是说,一个对象与生俱来就有
Object类型中所有的特征。

⑥ 继承也存在一些缺点,例如:CreditAccount 类继承 Account 类会导致它们之间的耦合度非常高,Account 类发生改变之后会马上影响CreditAccount 类

代码示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80

// 使用继承机制来解决代码复用问题。
// 继承也是存在缺点的:耦合度高,父类修改,子类受牵连。
public class ExtendsTest02{
public static void main(String[] args){
// 创建普通账户
Account act = new Account();
act.setActno("1111111");
act.setBalance(10000);
System.out.println(act.getActno() + ",余额" + act.getBalance());

// 创建信用账户
CreditAccount ca = new CreditAccount();
ca.setActno("2222222");
ca.setBalance(-10000);
ca.setCredit(0.99);
System.out.println(ca.getActno() + ",余额" + ca.getBalance() + ",信誉度" + ca.getCredit());
}
}

// 银行账户类
// 账户的属性:账号、余额
class Account{ // 父类
// 属性
private String actno;
private double balance;

// 构造方法
public Account(){

}
public Account(String actno, double balance){
this.actno = actno;
this.balance = balance;
}

// setter and getter
public void setActno(String actno){
this.actno = actno;
}
public String getActno(){
return actno;
}
public void setBalance(double balance){
this.balance = balance;
}
public double getBalance(){
return balance;
}
}

// 其它类型的账户:信用卡账户
// 账号、余额、信誉度
class CreditAccount extends Account{ //子类

// 属性
private double credit;

// 构造方法
public CreditAccount(){

}

public void doSome(){
//错误: actno 在 Account 中是 private 访问控制
//System.out.println(actno);
// 间接访问
//System.out.println(this.getActno());
System.out.println(getActno());
}

// setter and getter方法
public void setCredit(double credit){
this.credit = credit;
}
public double getCredit(){
return credit;
}

}