Java学习日志9

First Post:

Last Update:

Word Count:
2.6k

Read Time:
11 min

super关键字

super能出现在实例方法和构造方法中。

super的语法是:“super.”、“super()”

super不能使用在静态方法中。

super. 大部分情况下是可以省略的。

super.什么时候不能省略呢?
父类和子类中有同名属性,或者说有同样的方法,想在子类中访问父类的,super. 不能省略。

super() 只能出现在构造方法第一行,通过当前的构造方法去调用“父类”中
的构造方法,目的是:创建子类对象的时候,先初始化父类型特征

super的使用:
super.属性名 【访问父类的属性】
super.方法名(实参) 【访问父类的方法】
super(实参) 【调用父类的构造方法】

代码示例1:

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
/*
1、super是一个关键字,全部小写。
2、super和this对比着学习。
this:
this能出现在实例方法和构造方法中。
this的语法是:“this.”、“this()”
this不能使用在静态方法中。
this. 大部分情况下是可以省略的。
this.什么时候不能省略呢? 在区分局部变量和实例变量的时候不能省略。
public void setName(String name){
this.name = name;
}
this() 只能出现在构造方法第一行,通过当前的构造方法去调用“本类”中
其它的构造方法,目的是:代码复用。

super:
super能出现在实例方法和构造方法中。
super的语法是:“super.”、“super()”
super不能使用在静态方法中。
super. 大部分情况下是可以省略的。
super.什么时候不能省略呢? ???????
super() 只能出现在构造方法第一行,通过当前的构造方法去调用“父类”中
的构造方法,目的是:创建子类对象的时候,先初始化父类型特征。

3、super()
表示通过子类的构造方法调用父类的构造方法。
模拟现实世界中的这种场景:要想有儿子,需要先有父亲。

4、重要的结论:
当一个构造方法第一行:
既没有this()又没有super()的话,默认会有一个super();
表示通过当前子类的构造方法调用父类的无参数构造方法。
所以必须保证父类的无参数构造方法是存在的。

5、注意:
this()和super() 不能共存,它们都是只能出现在构造方法第一行。

6、无论是怎样折腾,父类的构造方法是一定会执行的。(百分百的。)

*/
public class SuperTest01{
public static void main(String[] args){
// 创建子类对象
/*
A类的无参数构造方法!
B类的无参数构造方法!
*/
new B();
}
}

class A extends Object{

// 建议手动的将一个类的无参数构造方法写出来。
public A(){
//super(); // 这里也是默认有这一行代码的。
System.out.println("A类的无参数构造方法!");
}

// 一个类如果没有手动提供任何构造方法,系统会默认提供一个无参数构造方法。
// 一个类如果手动提供了一个构造方法,那么无参数构造系统将不再提供。
public A(int i){
//super();
System.out.println("A类的有参数构造方法(int)");
}
}

class B extends A{
/*
public B(){
super();
System.out.println("B类的无参数构造方法!");
}
*/

public B(){
this("zhangsan");
// 调用父类中有参数的构造方法
//super(123);
System.out.println("B类的无参数构造方法!");
}

public B(String name){
super();
System.out.println("B类的有参数构造方法(String)");
}
}

代码示例2:

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
97
98
99
100
101
102
103
104
/*
1、举个例子:在恰当的时间使用:super(实际参数列表);
2、注意:在构造方法执行过程中一连串调用了父类的构造方法,
父类的构造方法又继续向下调用它的父类的构造方法,但是实际上
对象只创建了一个。

3、思考:“super(实参)”到底是干啥的?
super(实参)的作用是:初始化当前对象的父类型特征。
并不是创建新对象。实际上对象只创建了1个。

4、super关键字代表什么呀?
super关键字代表的就是“当前对象”的那部分父类型特征。

我继承了我父亲的一部分特征:
例如:眼睛、皮肤等.
super代表的就是“眼睛、皮肤等”。
“眼睛、皮肤等”虽然是继承了父亲的,但这部分是在我身上呢。

*/
// 测试程序
public class SuperTest03{
public static void main(String[] args){

CreditAccount ca1 = new CreditAccount();
System.out.println(ca1.getActno() + "," + ca1.getBalance() + "," + ca1.getCredit());

CreditAccount ca2 = new CreditAccount("1111", 10000.0, 0.999);
System.out.println(ca2.getActno() + "," + ca2.getBalance() + "," + ca2.getCredit());

}
}

// 账户
class Account extends Object{
// 属性
private String actno;
private double balance;

// 构造方法
public Account(){
//super();
//this.actno = null;
//this.balance = 0.0;
}
public Account(String actno, double balance){
// super();
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(String actno, double balance, double credit){

// 私有的属性,只能在本类中访问。
/*
this.actno = actno;
this.balance = balance;
*/

// 以上两行代码在恰当的位置,正好可以使用:super(actno, balance);
// 通过子类的构造方法调用父类的构造方法。
super(actno, balance);
this.credit = credit;
}

// 提供有参数的构造方法
public CreditAccount(){
//super();
//this.credit = 0.0;
}

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

}

代码示例2的JVM体现:

021super的原理.png

super不能省略时的JVM体现:

023SuperTest05.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
/*
猜数字游戏
一个类A有一个实例变量v,从键盘接收一个正整数作为实例变量v的初始值。
另外再定义一个类B,对A类的实例变量v进行猜测。
如果大了则提示大了
小了则提示小了
等于则提示猜测成功
*/
import java.util.Scanner;
public class HomeWork4GuessNumber {
public static void main(String[] args)
{
A a = new A(100);
B b = new B(a);
Scanner s = new Scanner(System.in);
while(true)
{
O.p("请输入要猜测的数字:");
int num = s.nextInt();
b.guess(num);
}
}
}

class A {
public int getV() {
return v;
}

private int v;
public A() {}

public A(int v) {
this.v = v;
}
}

class B
{ private A a;
public B() {}
public B(A a) {
this.a = a;
}

public void guess(int num)
{
int realNum = a.getV();
if(realNum == num)
{
O.p("猜对啦!");
System.exit(0);
}
else if(realNum > num)
{
O.p("猜小了");
}
else{
O.p("猜大了");
}
}

}

加减速:

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
/*请定义一个交通工具(Vehicle)的类
其中有属性:
速度(speed)
体积(size)等等
方法移动(move())
设置速度(setSpeed(int speed))
加速speedUp(),
减速speedDown()等等.

最后在测试类Vehicle中的main()中实例化一个交通工具对象
并通过方法给它初始化speed,size的值并且打印出来。
另外调用加速减速的方法对速度进行改变。*/
import java.util.Scanner;
public class HomeWork5Transport {
public static void main(String[] args) {
Vehicle v = new Vehicle();
Scanner s = new Scanner(System.in);
O.p("请输入初始速度");
v.setSpeed(s.nextInt());
O.p("请输入初始体积");
v.setSize(s.nextInt());
O.p("初始速度为" + v.getSpeed());
O.p("初始体积为" + v.getSize());
int i,u=1;
while(u == 1) {
O.p("输入1进行加速,输入2进行减速");
i = s.nextInt();
if (i == 1) {
v.setSpeed(v.speedUp(v.getSpeed()));
} else {
v.setSpeed(v.speedDown(v.getSpeed()));
}
O.p("此时的速度为" + v.getSpeed());
O.p("输入1将继续加/减速,输入2将自动结束程序");
u = s.nextInt();
}
}
}

class Vehicle
{
public int getSpeed() {
return speed;
}

public void setSpeed(int speed) {
this.speed = speed;
}

private int speed;
public int getSize() {
return size;
}
public void setSize(int size) {
this.size = size;
}
private int size ;

public int speedUp(int v) {
v++;
return v;
}

public int speedDown(int v) {
v--;
return v;
}
}

增减时间:

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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/*
在程序中经常要对时间进行操作但是并没有时间类型的数据。
那么我们可以自己实现一个时间类来满足程序中的需要。

定义名为MyTime的类其中应有三个整型成员时hour分minute秒second
为了保证数据的安全性这三个成员变量应声明为私有。

为MyTime类定义构造方法以方便创建对象时初始化成员变量。
再将时间信息打印出来。
*/
import java.util.Scanner;
public class HomeWork6Time {
public static void main(String[] args){
MyTime t = new MyTime();
Scanner s = new Scanner(System.in);
O.p("请输入初始小时");
t.setHour(s.nextInt());
O.p("请输入初始分钟");
t.setMinute(s.nextInt());
O.p("请输入初始秒数");
t.setSecond(s.nextInt());
O.p("您输入为" + t.getHour() + "小时" + t.getMinute() + "分钟" + t.getSecond() + "秒数");
int i=1;
while(i > 0 && i <7) {
O.p("增加1s请输入1,增加1min请输入2,增加1h请输入3");
O.p("减少1s请输入4,减少1min请输入5,减少1h请输入6,输入其他数字退出程序");
i = s.nextInt();
if (i == 1)
t.setSecond(t.addSecond(t.getSecond(),t.getMinute(),t.getHour()));
else if (i == 2)
t.setMinute(t.addMinute(t.getMinute(),t.getHour()));
else if (i == 3)
t.setHour(t.addHour(t.getHour()));
else if (i == 4)
t.setSecond(t.subSecond(t.getSecond(),t.getMinute(),t.getHour()));
else if (i == 5)
t.setMinute(t.subMinute(t.getMinute(),t.getHour()));
else if (i == 6)
t.setHour(t.subHour(t.getHour()));

O.p("时间为" + t.getHour() + "小时" + t.getMinute() + "分钟" + t.getSecond() + "秒数");
}
}
}

class MyTime
{
public int getHour() {
return hour;
}

public void setHour(int hour) {
this.hour = hour;
}

private int hour;

public int getMinute() {
return minute;
}

public void setMinute(int minute) {
this.minute = minute;
}

private int minute;

public int getSecond() {
return second;
}

public void setSecond(int second) {
this.second = second;
}

private int second;

public int addSecond(int s,int m,int h) {
s++;
if (s == 60)
{
s = 0;
this.setMinute(addMinute(m,h));
}
return s;

}

public int addMinute(int m,int h) {
m++;
if (m == 60)
{
m = 0;
this.setHour(addHour(h));

}
return m;
}

public int addHour(int h) {
h++;
return h;
}

public int subHour(int h) {
h--;
return h;
}

public int subMinute(int m,int h)
{
m--;
if(m<0)
{
m=59;
this.setHour(subHour(h));
}
return m;
}

public int subSecond(int s,int m,int h)
{
s--;
if(s<0)
{
s=59;
this.setMinute(subMinute(m,h));
}
return s;
}
}