搞点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;
		//转换成功
    }
}

强制转换可能会导致数据截断——整数长度不够的话会根据二进制安排一个不同的数 小数转整数会失去精度

自动数据转换

1
输出数据的时候也可以利用加号来达到类似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的值 
	}
}

至于一元/二元运算符之间的区别

一元运算符在运算时会使后者的数值进行隐式转换 与前者保持相同
而二元运算符则会按照前文讲过的规律自动转换数据 不注意会引发报错
2
(前者触发了将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 结构中只有第一个满足条件的分支会被执行
如果某个 ifelse if 条件为真 其后续的 else ifelse 将被跳过 和之前的短路机制类似

嵌套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中所有数字的和

二维数组

3

面向对象

什么是对象(面向对象思想):

  • 一切客观存在的事物都是对象, 万物皆对象 .
  • 任何对象,一定具有自己的 特征行为 .

特征: 称为属性 一般为名字 代表对象有什么
行为:成为方法 一般为动词 代表对象能做什么

程序中的对象

如何使用程序模拟现实世界,解决现实问题?

  • 首先, 在程序当中,必须具有和现实中相同的对象,用以模拟现实世界.
  • 然后,使用程序中的对象代表现实中的对象,并执行操作,进而解决现实问题.

这里我们举个例子 创建一个名为 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
4
默认值是可以改的 我们在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关键字

5
加了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

6
super和this差不多 都是在变量前边加 能够提高优先级
7

方法的重写

有的时候父类里定义的方法并没有写的很全 需要再加一些 就可以再进行重写
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.