搞点java
介绍
不多说了 接触点新的语言 指不定用得上呢
环境为windows11 java17
跳转
顺便做个学习记录吧
11/23 17:30 p24完成 19:30 p25完成
11/24 17:00 p26完成 17:30 p27完成
11/25 p28完成 p29完成 p30完成
11/26 p31完成 p32完成 p33完成 p34完成 p35完成 p36完成
p38 p39是教你下软件 这里用idea代替
p40 跳过
11/27 p41完成 看p51 到p56
11/28 p56完成 p57完成-p65完成
11/29 p66完成 p67完成 p68完成-p76-p79完成 p80完成
最近学的有点多了 得消化消化 先转移一下注意力吧
ps:大学竟然今后只学c++ 这下白搭了
正文
请注意java为大小写敏感的强类型语言(每个值的数据类型都不能随意变更)
javac编译的时候加上 -encoding utf-8
不然程序不认中文
helloworld程序
public class HelloWorld{
public static void main(String[] args) {
System.out.print("hello world");
}
}
//public所修饰的class必须与文件名保持一致 且一个java文件可以存在多个class 但编译后会分开
/*
多行注释
*/
/**
文档注释-用于自动生成帮助文件/在编译环境中生成简介
命令 javadoc -encoding utf-8 类名 (-d可指定输出目录)可以生成一系列帮助文件
*/
(windows系统需要提前配置环境变量)编译运行过程:
打开cmd 同目录下输入 javac 文件名.java
会出现一个.class文件 随后运行java 文件名
即可运行程序System.out.print为直接输出 System.out.println会在输出后自己换行
变量定义&赋值
public class output{
public static void main(String[] args) {
int money;
money = 100;
System.out.println(money);
}
}
定量名需要注意的几个点
1.不能以数字开头 可以包含数字 字母 下划线_
货币符号
2.不能和关键字 保留字重名 不能是 true false null
数据类型
分为基本数据类型 和 引用数据类型
基本数据类型分为整数 小数 布尔 字符
整数分为byte short int long(默认运算时为int 若需要为long类型赋值较大整数时 需要在数的后面加“L”)
分别占用1 2 4 8字节
二进制取值范围为2的7次方 15次方 31次方 63次方
小数分为float double(默认为double 若需要为float型赋值时 需要在数的后面加“F”)
分别占用4 8字节
布尔类型boolean占用4字节 取值为true(真)或者false(假)
字符类型只有个char 占2字节 取值范围0-65535
赋值的时候可以直接用单引号加字符 也可以用整数或进制
char c1 = 'A';
char c2 = 65;
char c3 = '\u00041';
在一些特殊情况下 使用转义字符
\n 换行
\t 缩进
\\ 反斜线
\' 单引号
\" 双引号
引用数据类型分为字符串 数组 对象
字符串类型只有string 可以表示一串的字符
类型转换
自动类型转换:
- 两种类型互相兼容
- 目标类型大于源类型
强制类型转换:
- 两种类型互相兼容
- 目标类型小于源类型
例:
自动转换
public class HelloWorld{
public static void main(String[] args) {
short s =123;
int i = s;
//转换成功
}
}
强制转换
public class HelloWorld{
public static void main(String[] args) {
short s =123;
byte b = s;
//转换失败
}
}
public class HelloWorld{
public static void main(String[] args) {
short s =123;
byte b = (byte)s;
//转换成功
}
}
强制转换可能会导致数据截断——整数长度不够的话会根据二进制安排一个不同的数 小数转整数会失去精度
自动数据转换
输出数据的时候也可以利用加号来达到类似c语言中占位符的效果
例:int a=1; System.out.println("a="+a);
输出结果就会是a=1
算术运算符
就是使两个数之间进行计算的符号
操作符 | 描述 |
---|---|
+ | 加、求和 |
- | 减、求差 |
* | 乘、求积 |
/ | 除、求商 |
% | 模、求余 |
还有俩一元运算符(只需要一个操作数的运算符)
操作符 | 描述 |
---|---|
++ | 递增、变量值+1 |
– | 递减、变量值-1 |
输出的时候为防止字符串优先级过高 可以使用括号
想要输出小数可以用(double)转数据类型
报错的小差分——整形除以0会抛异常说不能除以0
浮点除以0会说结果无限大(因为0是无限小)
0除以0会返回NaN
++和–在变量的前面/后面 运行结果会有所不同
当++、--运算符前置的时候,返回自加/自减后的值
当++、--运算符后置的时候,返回自加/自减前的值
赋值运算符
操作符 | 描述 |
---|---|
= | 直接赋值 |
+= | 求和后赋值 |
-= | 求差后赋值 |
*= | 求积后赋值 |
/= | 求商后赋值 |
%= | 求模后赋值 |
a+=b ----> a=a+b
(理论来说是相同的 但一元和二元运算符有区别 后面会说)
例题:交换两个变量的值
有两种方式 引入一个新的空变量 或者利用逆运算和赋值
//方法一 引入空变量
public class Main {
public static void main(String[] args) {
int a = 8;
int b = 10;
int temp;
temp = a; //将a的值存入temp中
a = b; //将a的值变为b
b = temp; //将temp中存储的a值放入b
}
}
//方法二 利用逆运算
public class Main {
public static void main(String[] args) {
int a = 8;
int b = 10;
a = a + b; //a赋值为a与b的和
b = a - b; //让b从两者之和中减去自身 得到a的值
a = a - b; //a从两者之和中再减去现在的b 得到b的值
}
}
至于一元/二元运算符之间的区别
一元运算符在运算时会使后者的数值进行隐式转换 与前者保持相同
而二元运算符则会按照前文讲过的规律自动转换数据 不注意会引发报错
(前者触发了将short强制转换成int的错误 而后者会隐式转换 没有问题)
其他运算符
关系运算符:两个操作数进行比较
操作符 | 描述 |
---|---|
> | 大于 |
< | 小于 |
>= | 大于等于 |
<= | 小于等于 |
== | 等于 |
!= | 不等于 |
这些返回的都是布尔值 true 或 false
逻辑运算符:两个布尔类型的操作数或表达式进行逻辑比较
操作符 | 语义 | 描述 |
---|---|---|
&& | 与(并且) | 两个操作数,同时为真,结果为真 |
|| | 或(或者) | 两个操作数,有一个为真,结果为真 |
! | 非(取反) | 意为“不是”,真就是假,假就是真 |
小知识-短路与:
在判断与的语句中 系统为了缩减所需时间
当前面任意一项为假导致结果为假时 会直接掐断判断的过程 让后半段不被运行
例:
int a = 8,b = 10;
System.out.println(a>9 && b++==10);
System.out.println(b);
由于前者a>9为假 b++的过程被直接掐断 导致b输出出来依旧是10
按位与(&)不会有短路机制 一路触发运行
相同的 ||(或)也分短路或和按位或(|)的区别 具体逻辑同上
三元运算符:将判断后的结果赋值给变量
操作符 | 语义 | 描述 |
---|---|---|
? : | 布尔表达式?结果一:结果二 | 当表达式结果为真,获得结果一 当表达式结果为假,获得结果二 |
运算符的优先级
括号优先
算数>关系>赋值
例: (d=a+b>c
)中优先计算a+b 后将a+b的值与c作比较 随后将布尔值赋予d
然后是先乘除后加减 逻辑运算中 非(!) 优先于 与(&&) 优先于或(||)
控制台输入
程序在运行的时候 可以在控制台手动录入数据 再让程序继续运行
而为了使用这个功能 我们需要导入java预先准备好的包
使用方式为 `import 包名.类名;
import java.util.Scanner; //导入java包
public class test{
public static void main(String[] args){
Scanner input = new Scanner(System.in); //定义扫描仪
System.out.println("请输入用户名:");
String name = input.next();
System.out.println("您输入的名字是"+name);
}
}
// 使用Scanner类中对应的方法(区分类型);
.nextInt(); //获得整数
.nextDouble(); //获得小数
.next(); //获得字符串
.next().charAt(0); //获得单个字符 0指取第一个位置的数
作业:将接受的汉字转为对应的编码值并输出
其实挺简单的 只要在输出的时候使用(int)进行强制转换即可
import java.util.Scanner; //导入java包
public class test{
public static void main(String[] args){
Scanner input = new Scanner(System.in); //定义扫描仪
System.out.println("请输入汉字:");
char name = input.next().charAt(0);
System.out.println("您输入的字符对应的int值是"+(int)name);
}
}
/*
输出:
请输入汉字:
我
您输入的字符对应的int值是25105
*/
if语句
if的结构没啥好讲的 就是根据布尔值进行结果的选择性运行
import java.util.*; //用星号可以直接引用所有util下的项 一劳永逸
public class testif {
public static void main(String[] args){
Scanner input =new Scanner(System.in);
System.out.println("input number:");
int score = input.nextInt();
if (score>60) {
System.out.println("你合格了");
}else{
System.out.println("你不过关");
}
}
}
/*
输出:
input number:
65
你合格了
input number:
32
你不过关
*/
if嵌套-else if
import java.util.*;
public class testif {
public static void main(String[] args){
Scanner input =new Scanner(System.in);
System.out.println("input number:");
int score = input.nextInt();
if (score > 100 || score < 0) {
System.out.println("?");
} else if (score == 100) {
System.out.println("满分");
} else if (score >= 90) {
System.out.println("优秀");
} else if (score >= 80) {
System.out.println("良好");
} else if (score >= 60) {
System.out.println("合格");
} else {
System.out.println("你完蛋了");
}
}
}
/*
输出:
input number:
100
满分
input number:
90
优秀
input number:
80
良好
input number:
60
合格
input number:
53
你完蛋了
*/
要注意在一组 if-else
结构中只有第一个满足条件的分支会被执行
如果某个 if
或 else if
条件为真 其后续的 else if
或 else
将被跳过 和之前的短路机制类似
嵌套if
基本就是if里套了个if….
import java.util.*;
public class testif {
public static void main(String[] args){
Scanner input =new Scanner(System.in);
System.out.println("input number:");
int score = input.nextInt();
if (score==100) {
System.out.println("满分");
}else if(score < 100 && score >= 90){
System.out.println("优秀");
if(score > 95){
System.out.println("差点满分了");
}else{
System.out.println("还是差点");
}
}else{
System.out.println("?");
}
}
}
/*
输出:
input number:
95
优秀
还是差点
input number:
98
优秀
差点满分了
*/
switch分支结构
import java.util.*;
public class testif {
public static void main(String[] args){
Scanner input =new Scanner(System.in);
System.out.println("input number:");
int score = input.nextInt();
switch (score/10) {
case 10:
System.out.println("牛逼");
break;
case 9:
System.out.println("优秀");
break;
default:
System.out.println("屁嘞");
break;
}
}
}
/*
输出:
input number:
100
牛逼
input number:
96
优秀
*/
整体逻辑 括号里的玩应和case对上了就触发后面的东西 对不上就触发default
假如case触发后没有break 则会一路往下继续运行
注意:switch可判断的类型为 byte short int char String(jdk7以上)
while循环
public class HelloWorld{
public static void main(String[] args) {
int i = 1;
while( i<=100 ){
System.out.println("第"+i+"次");
i++;
}
}
}
语法:括号里加判断式 大括号加逻辑代码 布尔值为1时 逻辑代码持续运行
do-while循环
public class HelloWorld{
public static void main(String[] args) {
int i = 1;
do{
System.out.println("第"+i+"次");
i++;
}while( i>=100 );
}
}
do-while循环先进行了一次循环操作之后,再进行布尔表达式的判断.
即使条件不满足 输出依旧执行了第1次
for循环
老样子 for后边的括号分三个部分
(初始部分(只执行一次); 循环条件; 迭代部分)
public class HelloWorld{
public static void main(String[] args) {
for(int i=1;i<=200;i++){
System.out.println("这是"+i);
}
}
}
控制循环的语句
一般是用在循环里来控制循环break
:终止、跳出switch、循环结构.continue
:结束本次 进入下一次循环.
public class HelloWorld{
public static void main(String[] args) {
for(int i=1;i<=200;i++){
if(i%4 == 0){
continue;
}
if (i == 99) {
break;
}
System.out.println("这是"+i);
}
}
}
该代码的运行结果是 能被4整除的数字没有输出 输出到98便停止了|
方法(类似于其它语言中的函数)
方法需要定义在类的内部 和main方法并列 不允许方法里再定义方法
public class HelloWorld{
public static void main(String[] args) {
for(int i=1;i<=20;i++){
say();
}
}
public static void say(String[] args) {
for(int i=1;i<=5;i++){
System.out.println("这是?"+i);
}
}
}
输出:重复20遍的1-5
方法后面的括号可以添加形式参数(等价于局部变量的声明)
这样以后在调用这个参数的时候就要在括号里加入对应的实际参数
public class HelloWorld{
public static void main(String[] args) {
for(int i=1;i<=5;i++){
say(11112);
}
}
public static void say(int word) {
for(int i=1;i<=5;i++){
System.out.println("这是?"+word);
}
}
}
输出: 25遍11112
也能通过逗号来传多个参数
public class HelloWorld{
public static void main(String[] args) {
for(int i=1;i<=5;i++){
say(11112,'啥');
}
}
public static void say(int word,char fuhao) {
for(int i=1;i<=5;i++){
System.out.println("这是"+fuhao+word);
}
}
}
输出:25遍这是啥11112
return和返回值
方法所返回的数据类型和具体内容由方法名称前的前一个项决定
public static void www() //void指返回空值
public static int www() //返回一个int的方法
至于返回使用return 数值;语句执行
public class HelloWorld{
public static void main(String[] args) {
for(int i=1;i<=5;i++){
int y = say(2,'啥');
System.out.println(y);
}
}
public static int say(int word,char fuhao) {
for(int i=1;i<=5;i++){
word++;
}
return word-1;
}
}
输出:返回了五个6
有返回的类型必须要保证在任何情况下都会返回一个值 不然便会报错
return用在void类型的方法中相当于直接终止该方法
方法调用与递归
当存在多个方法时 顺序为优先执行方法内部的代码 结束后 返回到调用的地方 再继续往下执行
递归指的是再方法内部再次调用自身的编程方式 但不正确使用容易出现内存问题
public class HelloWorld{
public static void main(String[] args) {
int num= f(10);
System.err.println(num);
}
public static int f(int n) {
return n==1?1:n*f(n-1);
}
}
数组
public class HelloWorld{
public static void main(String[] args) {
int[] a=new int[]{1,2,3,4,5};
}
}
声明一个数组: 数据类型[] 数组名;
分配数组空间: new 数据类型[长度];
声明并分配空间: 数据类型[] 数组名 = new 数组类型[长度]
声明并赋值:数据类型[] 数组名 = new 数据类型[]{1,2,3};
数据类型[] 数组名 = {1,2,3};
//期间不能换行
至于数组的组成 数组中的每个数据格被称为“数组元素”
对每个元素进行赋值或取值被称为“元素的访问”
访问元素的时候 需要使用“下标”(从0开始,依次+1,自动生成)
访问的语法:数组名[下标]; 存数据:a[0] = 10; 取数据 a[0];
public class HelloWorld{
public static void main(String[] args) {
int[] a = new int [5];
a[0]=5;
a[1]=3;
a[2]=4;
a[3]=7;
a[4]=10;
for(int i = 0;i < 5;i++){
System.out.println(a[i]);
}
}
}
输出:依次输出 5 3 4 7 10
想表示数组的长度 可以在数组名后加.length
import java.util.*;
public class HelloWorld{
public static void main(String[] args) {
int[] nums ={2,3,4,5,7,8,9,0,11};
Scanner input =new Scanner(System.in);
System.err.println("请输入一个整数:");
int num = input.nextInt();
boolean flag = false;
for(int i = 0;i < nums.length;i++){
if(nums[i]==num){
System.out.println(i);
flag = true;
break;
}
}
if (flag == false) {
System.err.println(-1);
}
}
}
上式所实现的内容:查看输入的数是否和数组中的元素对应 如果是 输出对应下标 如果不是 输出-1
数组的扩容
创建数组时 必须指定长度 并且在创建后不可更改
想要实现数组扩容 只能创建一个新的数组并导入旧数据
import java.util.Arrays;
public class test5{
public static void main(String[] args) {
int[] nums ={11,22,33,44,55};
int[] newints = new int[nums.length*2];
for(int i = 0;i<nums.length;i++){
newints[i]=nums[i];
}
System.err.println(Arrays.toString(newints));
}
}
// Arrays.toString可以实现将数组转为字符串后输出
// 输出: [11, 22, 33, 44, 55, 0, 0, 0, 0, 0]
除去这个比较麻烦的 还有两个更加快捷的方法
System.arraycopy(原数组,原数组起始,新数组,新数组起始,长度);
java.util.Arrays.copyOf(原数组,新长度); //返回带有原数值的新数组
import java.util.Arrays;
public class test5{
public static void main(String[] args) {
int[] nums ={11,22,33,44,55};
int[] newints = new int[nums.length*2];
int[] newints1 = {};
for(int i = 0;i<nums.length;i++){
newints[i]=nums[i];
}
nums = Arrays.copyOf(nums, 100);
System.out.println(Arrays.toString(newints));
System.out.println(Arrays.toString(nums));
}
}
//前面那个不好使 只用后边的
数组类型的参数
当然 数组也能拿去在方法里使用
import java.util.Arrays;
public class test5{
public static void main(String[] args) {
int[] nums ={1,2,3,4,5};
add(nums);
System.out.println(Arrays.toString(nums));
}
public static void add(int[] nums) {
for(int i=0;i<nums.length;i++){
nums[i] += 1;
}
}
}
// 输出了{2,3,4,5,6}
可以变长的参数
概念:可以接收多个同类型实参 个数不限 使用方式与数组相同
语法:数据类型… 形参名 //必须定义在形参列表的最后 且只能有一个
import java.util.Arrays;
public class test5{
public static void main(String[] args) {
add(1,23,4324,65345,23123);
}
public static void add(int... nums) {
int sum = 0;
for(int i = 0; i < nums.length; i++){
sum += nums[i];
}
System.out.println(sum);
}
}
// 输出了add中所有数字的和
二维数组
面向对象
什么是对象(面向对象思想):
- 一切客观存在的事物都是对象, 万物皆对象 .
- 任何对象,一定具有自己的 特征 和 行为 .
特征: 称为属性 一般为名字 代表对象有什么
行为:成为方法 一般为动词 代表对象能做什么
程序中的对象
如何使用程序模拟现实世界,解决现实问题?
- 首先, 在程序当中,必须具有和现实中相同的对象,用以模拟现实世界.
- 然后,使用程序中的对象代表现实中的对象,并执行操作,进而解决现实问题.
这里我们举个例子 创建一个名为 dog 的类(class) 为它定义特征(属性)和行为(方法)
// 这是Dog.java中的内容 声明了如何调用Dog的特征并使用其中的eat sleep行为
public class Dog {
String breed;
int age;
String sex;
String color;
public void eat(){
System.out.println("在吃东西");
}
public void sleep(){
System.out.println("在睡觉...");
}
}
// 以下是调用Dog类的dogtest.java中的内容
public class dogtest {
public static void main(String[] args) {
Dog mygo = new Dog();
mygo.breed = "萨摩耶";
mygo.age = 7;
mygo.color = "白";
mygo.sex = "公";
System.out.println(mygo.breed+"\t今年"+mygo.age+"岁\t是"+mygo.sex+"狗\t"+mygo.color+"毛");
mygo.eat();
mygo.sleep();
}
}
// 声明调用语句: 类名 引用名 = new 类名();
// 调用特征: 引用名.特征名 = 值; 相关数据类型在类里已经有定义
// 调用行为: 引用名.方法名();
当dogtest.java处不给变量赋值的话 会输出默认值
int对应0 string对应null double对应0.0 boolean对应false
默认值是可以改的 我们在dog.java里为变量赋值就可以了
public void eat(){
String breed="default";
System.out.println(breed+"在吃东西");
}
/*
输出:
null 今年0岁 是null狗 null毛
default在吃东西
null在睡觉...
这样设置的话会优先使用局部变量 要用实例变量需要在变量前加this.
*/
// dog.java
public void eat(){
String breed="default";
System.out.println(this.breed+"在吃东西");
}
// dogtest.java
mygo.breed = "萨摩耶";
// 输出
萨摩耶 今年7岁 是公狗 白毛
萨摩耶在吃东西
萨摩耶在睡觉...
加深印象再举个例子 student
// student.java
public class student {
String name;
int age;
String sex;
int score;
public void sayHi(){
System.out.println(name+"--"+age+"--"+sex+"--"+score);
}
}
//student5.java
public class student5 {
public static void main(String[] args) {
student wow = new student();
wow.name = "张三";
wow.age = 14;
wow.sex = "男";
wow.score = 99;
wow.sayHi();
}
}
//输出
张三--14--男--99
方法重载
通过多个相同名称的方法实现多个过程——例如实现“吃”的多个分支 吃水果 吃蔬菜 吃药
要求:
- 方法名称相同
- 参数列表不同(类型、个数、顺序)
- 与访问修饰符、返回值类型无关
好处:灵活 方便
//代码
public class test6 {
public static void main(String[] args) {
test(1);
test("烧烤",2);
}
public static void test(int a) {
System.out.println("吃吃吃!");
}
public static void test(String name,int b) {
System.out.println(name+"也吃吃吃!");
}
}
//结果
吃吃吃!
烧烤也吃吃吃!
构造方法
构造方法是类中的特殊方法,主要用于创建对象.
特点:
- 名称与类名完全相同
- 没有返回值类型
- 创建对象时,触发构造方法的调用,不可通过句点手动调用
注意:如果没有在类中显式定义构造方法,则编译器默认提供无参构造方法
//Person.java代码内容
class Person {
String name;
int age;
// 无参构造方法
Person() {
name = "未命名";
age = 0;
}
// 带一个参数的构造方法
Person(String name) {
this.name = name;
age = 0;
}
// 带两个参数的构造方法
Person(String name, int age) {
this.name = name;
this.age = age;
}
}
//Main.java中的内容
public class Main {
public static void main(String[] args) {
Person p1 = new Person();
Person p2 = new Person("Bob");
Person p3 = new Person("Charlie", 30);
System.out.println("p1: " + p1.name + ", " + p1.age);
System.out.println("p2: " + p2.name + ", " + p2.age);
System.out.println("p3: " + p3.name + ", " + p3.age);
}
}
//输出
p1: 未命名, 0
p2: Bob, 0
p3: Charlie, 30
this关键字
加了this之后 谁在调用当前对象 就套用哪个
面向对象的三大特性 分装 继承 多态
什么是封装
概念:尽可能隐藏对象的内部实现细节 控制对象的修改 访问权限
访问修饰符: private (可将属性修饰为私有,仅本类可见)
//student.java中的内容
public class student {
String name;
private int age;
String sex;
double score;
public void setAge(int age){
if(age>=0 && age<=160){
this.age = age;
}else{
this.age = 18;
}
}
public int getAge(){
return age;
}
}
//student5.java中的内容
public class student5 {
public static void main(String[] args) {
student s1 = new student();
s1.setAge(1000);
System.out.println(s1.getAge());
}
}
//输出
18 //超出范围时 age将被赋值18
通过设置private属性 外界访问将无法直接给private属性赋值 需要通过公共方法来进行
继承的概念
假如说要搞很多类 他们都有很多共同的性质 一个一个定义太麻烦了 可以定义一个父类 关键是在类后边使用extends
// Pet.java 中的内容
public class Pet {
String name;
int health;
int love;
public void eat(){
System.out.println(name+"吃东西呢");
}
public String getName(){
return name;
}
public void show(){
System.out.println(name+"-"+health+"-"+love);
}
}
//Dog.java中的内容
public class Dog extends Pet { //表明内容继承自Pet
String breed;
public void sleep(){
System.out.println(breed+"在睡觉...");
}
}
//test.java中的内容
public class test {
public static void main(String[] args) {
Dog d1 = new Dog();
d1.name="修购";
d1.health=99;
d1.love=132;
d1.breed="哈士奇";
d1.sleep();
d1.show();
}
}
//输出
哈士奇在睡觉...
修购-99-132
super和this差不多 都是在变量前边加 能够提高优先级
方法的重写
有的时候父类里定义的方法并没有写的很全 需要再加一些 就可以再进行重写
1.重写时访问修饰符的等级必须相等或是放大(父类中方法为protected 子类重写时只能改为protected或public ) 改小会报错
2.返回值类型可以和父类一致,也可以是父类返回类型的子类
3.方法名必须完全一样
4.参数也要注意 不然不是重写而是重载
//父类Pet.java
public class Pet {
String name;
int health;
int love;
public void eat(){
System.out.println(name+"吃东西呢");
}
public String getName(){
return name;
}
public void show(){
System.out.println(name+"-"+health+"-"+love);
}
}
//子类Dog.java
public class Dog extends Pet {
String breed;
public void show(){
System.out.println(name+breed+"在睡觉...");
}
}
//test.java
public class test {
public static void main(String[] args) {
Dog d1 = new Dog();
d1.name="修购";
d1.health=99;
d1.love=132;
d1.breed="哈士奇";
d1.show();
}
}
//输出
修购哈士奇在睡觉...
输出的规则参照了Dog.java而不是Pet.java 说明成功重写
继承下的构造执行
- 在具有继承关系的对象创建中,构建子类对象会先调用父类构造.
- 由父类的共性内容,叠加子类的都有内容,组合成完整的子类对象.
多态
指的是父类引用指向子类对象 从而产生多种形态
//父类Pet.java
public class Pet {
String name;
int health;
int love;
public void show() {
System.out.println(name + "在跳舞");
}
}
//子类Dog.java
public class Dog extends Pet {
@Override
public void show() {
System.out.println(name + "在睡觉...");
}
}
//子类Cat.java
public class Cat extends Pet {
@Override
public void show() {
System.out.println(name + "在喵喵叫...");
}
}
//test.java
public class Test {
// 通过形参实现多态的方法
public static void letPetPerform(Pet pet) {
pet.show(); // 调用实际对象的 show 方法
}
public static void main(String[] args) {
Pet dog = new Dog();
dog.name = "修购";
dog.health = 99;
dog.love = 132;
Pet cat = new Cat();
cat.name = "咪咪";
cat.health = 95;
cat.love = 120;
// 使用形参多态
letPetPerform(dog); // 输出: 修购在睡觉...
letPetPerform(cat); // 输出: 咪咪在喵喵叫...
}
}
结尾/引用
We are just1 another visitor in a transient world.