0%

Java 多态理解

多态的3个必要条件:

1.继承 2.重写 3.父类引用指向子类对象。

要理解多态性,首先要知道什么是“向上转型”。

我定义了一个子类Cat,它继承了Animal类,那么后者就是前者是父类。我可以通过

1
Cat c = new Cat();

实例化一个Cat的对象,这个不难理解。
但当我这样定义时:

1
Animal a = new Cat();

表示定义了一个Animal类型的引用,指向新建的Cat类型的对象。由于Cat是继承自它的父类Animal,所以Animal类型的引用是可以指向Cat类型的对象的。


那么这样做有什么意义呢?

因为子类是对父类的一个改进和扩充,所以一般子类在功能上较父类更强大,属性较父类更独特, 定义一个父类类型的引用指向一个子类的对象既可以使用子类强大的功能,又可以抽取父类的共性。

父类引用的特点:

父类类型的引用可以调用父类中定义的所有属性和方法;

而无法调用子类中定义的,但是父类中没有的方法。

同时,

父类中的一个方法只有在父类中定义而在子类中没有重写的情况下,才可以被父类类型的引用调用;

对于父类中定义的方法,如果子类中重写了该方法,那么父类类型的引用将会调用子类中的这个方法,这就是动态连接。也可以叫做动态绑定。

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
class Father {
public void func1()

{
func2();
}

// 这是父类中的func2()方法,因为下面的子类中重写了该方法 ,所以在父类类型的引用中调用时,这个方法将不再有效,取而代之的是将调用子类中重写的func2()方法
public void func2() {
System.out.println("AAA");
}
}
class Child extends Father { // func1(int i)是对func1()方法的一个重载由于在父类中没有定义这个方法,所以它不能被父类类型的引用调用所以在下面的main方法中child.func1(68)是不对的
public void func1(int i) {
System.out.println("BBB");
} // func2()重写了父类Father中的func2()方法 如果父类类型的引用中调用了func2()方法,那么必然是子类中重写的这个方法
public void func2() {
System.out.println("CCC");
}
}
public class PolymorphismTest {
public static void main(String[] args) {
Father child = new Child();
child.func1();// 打印结果将会是什么? } }

}
}

上面的程序是个很典型的多态的例子。

1
子类Child继承了父类Father,并重载了父类的func1()方法,重写了父类的func2()方法。重载后的 func1(int i)和func1()不再是同一个方法,由于父类中没有func1(int i),那么,父类类型的引用child就不能调用func1(int  i)方法。而子类重写了func2()方法,那么父类类型的引用child在调用该方法时将会调用子类中重写的func2()  

那么该程序将会打印出什么样的结果呢? 很显然,应该是“CCC”。

对于多态,可以总结它为:

1
2
3
4
5
6
7
一、使用父类类型的引用指向子类的对象;

二、该引用只能调用父类中定义的方法和变量;

三、如果子类中重写了父类中的一个方法,那么在调用这个方法的时候,将会调用子类中的这个方法;(动态连接、动态调用)

四、变量不能被重写(覆盖),”重写“的概念只针对方法,如果在子类中”重写“了父类中的变量,那么在编译时会报错。

Java基础语法

1-1如何命名Java变量

enter image description here

以下变量的命名都是符合规范的:

enter image description here

错误的例子
enter image description here

优秀攻城师的习惯:

1、变量名由多单词组成时,第一个单词的首字母小写,其后单词的首字母大写,俗称骆驼式命名法(也称驼峰命名法),如 myAge

2、变量命名时,尽量简短且能清楚的表达变量的作用,做到见名知意。如:定义变量名 stuName 保存“学生姓名”信息

PS: Java 变量名的长度没有限制,但 Java 语言是区分大小写的,所以 price 和 Price 是两个完全不同的变量哦!

1-2 Java中的数据类型

Java 语言是一种强类型语言。
通俗点说就是,在 Java 中存储的数据都是有类型的,而且必须在编译时就确定其类型。
Java 中有两类数据类型:

enter image description here

在 Java 的领域里,基本数据类型变量存的是数据本身,而引用类型变量存的是保存数据的空间地址。

说白了,基本数据类型变量里存储的是直接放在抽屉里的东西,而引用数据类型变量里存储的是这个抽屉的钥匙,钥匙和抽屉一一对应。

常用的基本数据类型有:

enter image description here

例子:
enter image description here

1-3 Java中的自动类型转换

当然自动类型转换是需要满足特定的条件的:

  1. 目标类型能与源类型兼容,如 double 型兼容 int 型,但是 char 型不能兼容 int 型

enter image description here

  1. 目标类型大于源类型,如 double 类型长度为 8 字节, int 类型为 4 字节,因此 double 类型的变量里直接可以存放 int 类型的数据,但反过来就不可以了

enter image description here

1-4 Java中的强制类型转换

例如,当程序中需要将 double 型变量的值赋给一个 int 型变量,该如何实现呢?

显然,这种转换是不会自动进行的!因为 int 型的存储范围比 double 型的小。此时就需要通过强制类型转换来实现了。

enter image description here
()里面填入要转换成的类型

1-5 Java常量的应用

所谓常量,我们可以理解为是一种特殊的变量,它的值被设定后,在程序运行过程中不允许改变。

语法:final 常量名 = 值;

enter image description here

程序中使用常量可以提高代码的可维护性。

例如,在项目开发时,我们需要指定用户的性别,此时可以定义一个常量 SEX,赋值为 “男”,在需要指定用户性别的地方直接调用此常量即可,避免了由于用户的不规范赋值导致程序出错的情况。

伙计们注意啦:常量名一般使用大写字符

1-6 如何在Java中使用注释

Java 中注释有三种类型:单行注释、多行注释、文档注释

enter image description here

2-1 Java中的算术运算符

Java 中常用的算术运算符:

enter image description here

其中,++ 和 – 既可以出现在操作数的左边,也可以出现在右边,但结果是不同滴

例1:
enter image description here

运行结果:
enter image description here

例2:
enter image description here

运行结果:
enter image description here

一定要注意哦!自增和自减运算符只能用于操作变量,不能直接用于操作数值或常量!

例如 5++ 、 8- - 等写法都是错误滴!

2-2 Java中的赋值运算符

赋值运算符是指为变量或常量指定数值的符号。如可以使用 “=” 将右边的表达式结果赋给左边的操作数。

Java 支持的常用赋值运算符,如下表所示:

enter image description here

例子:请在编辑器中,空白处编写代码,应用赋值运算符实现如下结果:

enter image description here

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
public class HelloWorld{
public static void main(String[] args) {
int one = 10 ;
int two = 20 ;
int three = 0 ;
three = one+two;
System.out.println("three = one +two ==>"+ three);
three +=one;
System.out.println("three += one ==>"+ three);
three -= one;
System.out.println("three -= one ==>"+ three);
three *= one;
System.out.println("three *= one ==>"+ three);
three /= one;
System.out.println("three /= one ==>"+ three);
three %= one;
System.out.println("three %= one ==>"+ three);

}
}

"""
three = one +two ==>30
three += one ==>40
three -= one ==>30
three *= one ==>300
three /= one ==>30
three %= one ==>0
"""

2-3 Java中的比较运算符

比较运算符用于判断两个数据的大小,例如:大于、等于、不等于。比较的结果是一个布尔值( true 或 false )。

Java 中常用的比较运算符如下表所示:

enter image description here

注意哦:

1、 > 、 < 、 >= 、 <= 只支持左右两边操作数是数值类型

2、 == 、 != 两边的操作数既可以是数值类型,也可以是引用类型

3、 = (一个等号)表示赋值

2-4 Java中的逻辑运算符

逻辑运算符主要用于进行逻辑运算。Java 中常用的逻辑运算符如下表所示:

enter image description here

我们可以从“投票选举”的角度理解逻辑运算符:

1、 与:要求所有人都投票同意,才能通过某议题

2、 或:只要求一个人投票同意就可以通过某议题

3、 非:某人原本投票同意,通过非运算符,可以使其投票无效

4、 异或:有且只能有一个人投票同意,才可以通过某议题

当使用逻辑运算符时,我们会遇到一种很有趣的“短路”现象。

譬如:( one > two ) && ( one < three ) 中,如果能确定左边 one > two 运行结果为 false , 则系统就认为已经没有必要执行右侧的 one < three 啦。

同理,在( one > two ) || ( one < three ) 中,如果能确定左边表达式的运行结果为 true , 则系统也同样会认为已经没有必要再进行右侧的 one < three 的执行啦!

2-5 Java中的条件运算符

条件运算符( ? : )也称为 “三元运算符”。

语法形式:布尔表达式 ? 表达式1 :表达式2

运算过程:如果布尔表达式的值为 true ,则返回 表达式1 的值,否则返回 表达式2 的值

例如:
enter image description here

因为,表达式 8>5 的值为 true ,所以,返回: 8大于5

1
2
3
4
5
6
7
public class HelloWorld{
public static void main(String[] args) {
int score=68;
String mark = (score>60) ? "及格" : "不及格";
System.out.println("考试成绩如何:"+mark);
}
}

2-6 Java中运算符的优先级

所谓优先级,就是在表达式中的运算顺序。Java 中常用的运算符的优先级如下表所示:
enter image description here

实际上没必要去死记运算符的优先级顺序,实际开发中,一般会使用小括号辅助进行优先级管理。例如:
enter image description here

3-1 Java条件语句之 if

语法:
enter image description here

执行过程:
enter image description here

例子 :判断变量 one 的值是否是偶数

1
2
3
4
5
6
7
8
public class HelloWorld {
public static void main(String[] args) {
int one = 20 ;
if (one%2 ==0){
System.out.println("one是偶数");
}
}
}

3-2 Java条件语句之 if…else

if…else 语句的操作比 if 语句多了一步: 当条件成立时,则执行 if 部分的代码块; 条件不成立时,则进入 else 部分。

语法:
enter image description here

执行过程:
enter image description here

例子:如果年龄大于等于 18 岁,则提示成年了,否则提示未成年

1
2
3
4
5
6
7
8
9
10
public class HelloWorld {
public static void main(String[] args) {
int age=25;
if(age>=18){
System.out.println("成年");
}else{
System.out.println("未成年");
}
}
}

3-3 Java条件语句之多重 if

多重 if 语句,在条件 1 不满足的情况下,才会进行条件 2 的判断;当前面的条件均不成立时,才会执行 else 块内的代码。

语法:
enter image description here

执行过程:
enter image description here

例子:假设年龄大于 60 岁,则提示“老年”;如果年龄介于 40 岁至 60 岁之间,则提示“中年”;如果年龄介于 18 岁至 40 岁之间,则提示“少年”; 18 岁以下则提示“童年”。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class HelloWorld {
public static void main(String[] args) {
int age=25;
if (age>60){
System.out.println("老年");
}else if(age>40){
System.out.println("中年");
}else if(age>18){
System.out.println("少年");
}else {
System.out.println("童年");
}
}
}

3-4 Java条件语句之嵌套 if

嵌套 if 语句,只有当外层 if 的条件成立时,才会判断内层 if 的条件。

语法:
enter image description here

执行过程:
enter image description here

例如:
例如,活动计划的安排,如果今天是工作日,则去上班,如果今天是周末,则外出游玩;同时,如果周末天气晴朗,则去室外游乐场游玩,否则去室内游乐场游玩。
enter image description here

3-5 Java循环语句之 for

语法:
enter image description here

执行过程:

<1>、 执行循环变量初始化部分,设置循环的初始状态,此部分在整个循环中只执行一次

<2>、 进行循环条件的判断,如果条件为 true ,则执行循环体内代码;如果为 false ,则直接退出循环

<3>、 执行循环变量变化部分,改变循环变量的值,以便进行下一次条件判断

<4>、 依次重新执行< 2 >、< 3 >、< 4 >,直到退出循环

需要留心的几个小细节:

1、 for 关键字后面括号中的三个表达式必须用 “;” 隔开,三个表达式都可以省略,但 “;” 不能省略。

a. 省略“循环变量初始化”,可以在 for 语句之前由赋值语句进行变量初始化操作,如:
enter image description here

b. 省略“循环条件”,可能会造成循环将一直执行下去,也就是我们常说的“死循环”现象,如:
enter image description here
在编程过程中要避免“死循环”的出现,因此,对于上面的代码可以在循环体中使用 break 强制跳出循环。

c. 省略“循环变量变化”,可以在循环体中进行循环变量的变化,如:
enter image description here

2、 for 循环变量初始化和循环变量变化部分,可以是使用 “,” 同时初始化或改变多个循环变量的值,如:
enter image description here

代码中,初始化变量部分同时对两个变量 i 和 j 赋初值,循环变量变化部分也同时对两个变量进行变化,运行结果:
enter image description here

3、 循环条件部分可以使用逻辑运算符组合的表达式,表示复杂判断条件,但一定注意运算的优先级,如:
enter image description here
代码中,必须同时满足变量 i 小于 10 ,并且 i 不等于 5 时才会进行循环,输出变量 i 的值。

例子:计算 1 到 100 之间不能被 3 整除的数之和

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class HelloWorld {
public static void main(String[] args) {
int sum = 0; // 保存不能被3整除的数之和

// 循环变量 i 初始值为 1 ,每执行一次对变量加 1,只要小于等于 100 就重复执行循环
for (int i = 1; i<=100 ; i++ ) {

// 变量 i 与 3 进行求模(取余),如果不等于 0 ,则表示不能被 3 整除
if (i % 3 != 0) {
sum = sum + i; // 累加求和
}
}

System.out.println("1到100之间不能被3整除的数之和为:" + sum);
}
}

3-6 Java循环跳转语句之 break

break 语句退出指定的循环,直接执行循环后面的代码。

比如,如在参加 10000 米长跑时,才跑了 500 米就由于体力不支,需要退出比赛。

实现代码:
enter image description here

运行结果:
enter image description here

例子:循环将 1 到 10 之间的整数相加,如果累加值大于 20,则跳出循环,并输出当前的累加值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class HelloWorld {
public static void main(String[] args) {

// 保存累加值
int sum = 0;

// 从1循环到10
for (int i = 1; i <= 10; i++) {

// 每次循环时累加求和
sum = sum + i;

// 判断累加值是否大于20,如果满足条件则退出循环
if ( sum>20 ) {

System.out.print("当前的累加值为:" + sum);
break; //退出循环
}
}
}
}

3-7 Java循环跳转语句之 continue

continue 的作用是跳过循环体中剩余的语句执行下一次循环。

例如,打印 1–10 之间所有的偶数,使用 continue 语句实现代码为:
enter image description here

运行结果:
enter image description here

例子: 求 1 到 10 之间的所有偶数的和。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/*定义一个变量 sum 保存累加值,定义一个变量 i 保存 1 到 10 之间的整数,循环遍历并进行判断,如果 i 不能被 2 整除,则结束本次循环,继续执行下一次循环,否则进行累加求和。
*/

public class HelloWorld {
public static void main(String[] args) {
int sum = 0; // 保存累加值
for (int i = 1; i <= 10; i++) {
// 如果i为奇数,结束本次循环,进行下一次循环
if ( i % 2 !=0 ) {
continue;
}
sum = sum + i;
}
System.out.print("1到10之间的所有偶数的和为:" + sum);
}
}