Java分为三个体系:
-
JavaSE(J2SE)(Java2 Platform Standard Edition,java平台标准版)
-
JavaEE(J2EE)(Java 2 Platform,Enterprise Edition,java平台企业版)
-
JavaME(J2ME)(Java 2 Platform Micro Edition,java平台微型版)。
JRE和JDK:
-
JVM(Java Virtual Machine ):Java虚拟机,简称JVM,是运行所有Java程序的假想计算机,是Java程序的运行环境,是Java 最具吸引力的特性之一。我们编写的Java代码,都运行在
JVM
之上。 -
JRE (Java Runtime Environment) :是Java程序的运行时环境,包含
JVM
和运行时所需要的核心类库 。 -
JDK:是Java程序开发工具包,包含JRE 和开发人员使用的工具。
-
JDK>JRE>JVM
Java语言有三大特性:封装、继承、多态。
-
封装:主要是将类中的部分代码实现细节隐藏、封装起来,不直接对外提供访问;
-
继承:主要体现的父子类的关系上,提高了软件的可重用性和可扩展性;
-
多态:包括编译时多态和运行时多态,通过调用不同参数或名称的方法来决定父类对象动态调用哪个子类方法,增强了代码的灵活度。
Java的特点:
- 面向对象:Java语言提供类、接口和继承等面向对象的特性,为了简单起见,只支持类之间的单继承,但支持接口之间的多继承,并支持类与接口之间的实现机制(关键字为implements)。Java语言全面支持动态绑定
- 跨平台:基于JVM(Java虚拟机),是Java程序的运行环境,编写的Java代码都运行在JVM上。
- 简单性:Java语言的语法与c和c++接近,丢弃了c++中复杂的特性,将指针改为引用,并提供了自动的废料收集,使程序员不必为内存管理而担忧。
- 解释执行:Java程序在Java平台上被编译为字节码格式,然后可以在实现这个Java平台的任何系统中运行。在运行时,Java平台中的Java解释器对这些字节码进行解释执行,执行过程中需要的类在联接阶段被载入到运行环境中。
- 支持多线程:在Java语言中,线程是一种特殊的对象,它必须由Thread类或其子(孙)类来创建。通常有两种方法来创建线程:其一,使用型构为Thread(Runnable)的构造子类将一个实现了Runnable接口的对象包装成一个线程,其二,从Thread类派生出子类并重写run方法,使用该子类创建的对象即为线程。值得注意的是Thread类已经实现了Runnable接口,因此,任何一个线程均有它的run方法,而run方法中包含了线程所要运行的代码。线程的活动由一组方法来控制。Java语言支持多个线程的同时执行,并提供多线程之间的同步机制(关键字为synchronized)。
- 分布式:Java语言支持Internet应用的开发,在基本的Java应用编程接口中有一个网络应用编程接口(java net),它提供了用于网络应用编程的类库,包括URL、URLConnection、Socket、ServerSocket等。Java的RMI(远程方法激活)机制也是开发分布式应用的重要手段。
- 健壮性:Java的强类型机制、异常处理、垃圾的自动收集等是Java程序健壮性的重要保证。对指针的丢弃是Java的明智选择。Java的安全检查机制使得Java更具健壮性。
- 高性能:与那些解释型的高级脚本语言相比,Java的确是高性能的。事实上,Java的运行速度随着JIT(Just-In-Time)编译器技术的发展越来越接近于C++。
- 安全性:Java通常被用在网络环境中,为此,Java提供了一个安全机制以防恶意代码的攻击。除了Java语言具有的许多安全特性以外,Java对通过网络下载的类具有一个安全防范机制(类ClassLoader),如分配不同的名字空间以防替代本地的同名类、字节代码检查,并提供安全管理机制(类SecurityManager)让Java应用设置安全哨兵。
Java的数据类型:
主要的基本数据类型有:
- byte:1个字节,表示8位二进制,范围是-128到127
- short:2个字节,表示16位二进制,范围是-32768到32767
- int:4个字节,表示32位二进制,范围是-2147483648到2147483647
- Long:8个字节,表示64位二进制,范围很大
- Float:4个字节,浮点数,声明需要加上F
- double:8个字节,浮点数
- char:2个字节,表示Unicode字符
- boolean:表示布尔值,true或false占1个字节
主要的引用数据类型有:
- 类(Class):定义新类型,封装数据和功能
- 数组(Array):用于存储多个值
- 接口(Interface):定义类型,封装抽象方法
- 枚举(Enumeration):定义有限集合的值
- 注解(Annotation):提供额外的信息,用于各种目的,如编译器提示等
Java中数值类型默认为int
byte + byte => int
short + int => int
int + long => long
float + double => double
byte b = 10;
b = (byte)(b + 100); // 需要强制转换
命名规范:
- 包名规范:全部字母小写。com.hopu.test。
- -类名规范:首字母大写,后面每个单词首字母大写(大驼峰式)。HelloWorld。
- 方法名规范: 首字母小写,后面每个单词首字母大写(小驼峰式)。 methodTestDemo。
- 变量名规范:首字母小写,后面每个单词首字母大写(小驼峰式)。int varDemo =10。
- 常量名规范:所有字母大写,多个单词之间有下划线_分隔。String DB_URL="http://xxx"。
运算符:
算数运算符 | 作用 | 例子(a=11,b=2) |
---|---|---|
+ | 加法运算,字符串连接运算 | 13=a+b; |
- | 减法运算 | 9=a-b; |
* | 乘法运算 | 22=a*b; |
/ | 除法运算,取整除结果 | 5=a/b; |
% | 取模运算,两个数字相除取余数 | 1=a%b; |
++ | 自增: 操作数的值增加1 | a++或++a,a的值都为12 |
-- | 自减: 操作数的值减少1 | a--或--a,a的值都为10 |
++与--运算符
-
++
运算,变量自己增长1。反之,--
运算,变量自己减少1,用法与++
一致。 -
++a:先+1后运算
-
a++:先运算后+1
赋值运算符:
符号 | 作用 | 说明 |
---|---|---|
= | 赋值 | a=10,将10赋值给变量a |
+= | 加后赋值 | a+=b,将a+b的值给a a=a+b |
-= | 减后赋值 | a-=b,将a-b的值给a a=a-b |
*= | 乘后赋值 | a*=b,将a×b的值给a |
/= | 除后赋值 | a/=b,将a÷b的商给a a=a/b |
%= | 取余后赋值 | a%=b,将a÷b的余数给a a=a%b |
运算符有自动强制类型转换
public static void main(String[] args){
short s = 1;
s+=1;
System.out.println(s);
}
关系运算符:
符号 | 说明 |
---|---|
== | a==b,判断a和b的值是否相等,成立为true,不成立为false |
> | a>b,判断a是否大于b,成立为true,不成立为false |
>= | a>=b,判断a是否大于或者等于b,成立为true,不成立为false |
< | a<b,判断a是否小于b,成立为true,不成立为false |
<= | a<=b,判断a是否小于或者等于b,成立为true,不成立为false |
!= | a!=b,判断a和b的值是否不相等,成立为true,不成立为false |
逻辑运算符:
符号 | 作用 | 说明 |
---|---|---|
& | 逻辑与 | a&b,a和b都是true,结果为true,否则为false 并且关系 |
| | 逻辑或 | a|b,a和b都是false,结果为false,否则为true 或者关系 |
^ | 逻辑异或 | a^b,a和b结果不同为true,相同为false |
! | 逻辑非 | !a,结果和a的结果正好相反 |
&& | 短路与 | 1. 两边都是true,结果是true 2. 一边是false,结果是false 短路与特点:符号左边是false,右边不再运算 |
|| | 短路或 | 1. 两边都是false,结果是false 2. 一边是true,结果是true 短路或特点: 符号左边是true,右边不再运算 |
三元运算符:
三元运算符也叫三目运算符。
三元运算符格式: 数据类型 变量名 = 布尔类型表达式?结果1:结果2
public static void main(String[] args) {
int a = 20;
int b = 10;
int max = (a>b ? a : b);//max赋值为 a,b中较大的值
System.out.println(max);//20
int min = (a<b ? a : b);//min赋值为 a,b中较小的值
System.out.println(min);//10
}
位运算符:
符号 | 作用 | 说明 |
---|---|---|
& | 按位与 | 两数同位对比,有0则为0 |
| | 按位或 | 两数同位对比,有1则为1 |
^ | 按位异或 | 两数同位对比,不同为1,相同为0 |
~ | 按位取反 | 针对一个数,操作数的每一位都取反 |
<< | 按位左移 | 针对一个数,操作数的每位向左移动指定位数,最高位丢弃,尾部空位补0(相当于乘以2的n次方) |
>> | 按位右移 | 针对一个数,操作数的每位向右移动指定位数,头部空位补符号位数,移除部分丢弃 |
>>> | 无符号右移 | 针对一个数,操作数的每位向右移动指定位数,无论符号数头部都补0,移除部分丢弃 |
public static void main(String[] args) {
// 方法1:引入第三方变量进行互换(适用于整型/字符串型)
int temp = a;
a = b;
b = temp;
System.out.println(a + "和" + b);
// 方法2:求和再减
a = a + b;
b = a - b;
a = a - b
System.out.println(a + "和" + b);
// 使用位运算符
a = a ^ b;
b = a ^ b;
a = a ^ b;
System.out.println(a + "和" + b);
}
运算符优先级:
数据输入:
Scanner类:
数据类型 变量名 = new 数据类型(参数列表);
Scanner scanner = new Scanner(System.in);
scanner.nextInt();
分支结构:
- 顺序结构
- 分支结构
- 循环结构
switch:case中不写break,会出现穿透现象,会继续向后运行,直到遇到break
switch中的表达式:支持byte、short、int、Long、char、boolean(Java8以后支持)、String、枚举
public static void main(String[] args) {
//定义月份变量,判断季节
int month = 6;
//switch语句实现选择
switch(month) {
case 12:
case 1:
case 2:
System.out.println("冬季");
break;
case 3:
case 4:
case 5:
System.out.println("春季");
break;
case 6:
case 7:
case 8:
System.out.println("夏季");
break;
case 9:
case 10:
case 11:
System.out.println("秋季");
break;
default:
System.out.println("你输入的月份数字有误");
break;
}
}
循环语句:
for(初始化表达式①; 布尔表达式②; 步进表达式④){
循环体③
}
初始化表达式①
while(布尔表达式②){
循环体③
步进表达式④
}
初始化表达式①
do{
循环体③
步进表达式④
}while(布尔表达式②);
三种循环的区别:
-
for循环和while循环先判断条件是否成立,然后决定是否执行循环体(先判断后执行)
-
do...while循环先执行一次循环体,然后判断条件是否成立,是否继续执行循环体(先执行后判断)
-
for循环和while的区别
-
for循环用在循环次数已知的情况下,可以控制遍历次数;
-
while和do...while循环还可以用在循环次数未知的情况下。
-
三种循环的区别总结:
1、建议使用的顺序:for,while,do-while 2、循环次数确定的话,建议使用for,循环次数不确定建议使用while 3、do-while循环来讲的话,至少执行一次
跳出语句关键字:
-
break
-
continue
public static void main(String[] args) {
//外层循环控制行
a: for (int i = 1; i <= 9; i++) {
// 内层循环控制列
for (int j = 1; j <= i; j++) {
if(j>=5) {
break a;
}
//不换行\t表示制表符
System.out.print(i + "*" + j + "="+i*j+"\t");
}
// 需要一次换行
System.out.println();
}
}
随机数:
Random random = new Random();
int num = random.nextInt(10);
解释: 10代表的是一个范围,如果括号写10,产生的随机数就是0(包括)-9(包括),括号写20,参数的随机数则是0(包括)-19(包括)
一维数组:
数据类型[] 数组名 = new 数据类型[长度];
数据类型[] 数组名 = new 数据类型[]{元素1,元素2,元素3...};
数据类型[] 数组名 = {元素1,元素2,元素3...};
获取:数组名[索引]
二维数组:
数据类型[][] 数组名字 = new 数据类型[长度][长度];
数据类型[][] 数组名字 = new 数据类型[长度][];
数据类型[][] 数组名字 = new 数据类型[][]{{元素1},{元素2}...};
数据类型[][] 数组名字 = {{元素1},{元素2}...};
获取:数组名[索引][索引];
数组排序:
冒泡排序:
public static void main(String[] args) {
// 定义一个元素顺序杂乱的数组
int[] arr = { 4, 1, 3, 6, 2, 5};
// 外层循环表示比较轮数
for (int i = 1; i <= arr.length-1; i++) {
// 内层循环对比相邻两个数
for (int j = 0; j < arr.length-i; j++) {
// 定义一个临时变量
int tempMax=0;
// 进行元素位置交换
if(arr[j]>arr[j+1]) {
tempMax=arr[j];
arr[j]=arr[j+1];
arr[j+1]=tempMax;
}
}
}
// 打印
System.out.println(Arrays.toString(arr));
}
优化冒泡排序:
- 添加方法签名:将排序逻辑封装在一个单独的方法中,使代码更具可读性和可重用性。
- 优化冒泡排序:在某次循环中如果没有发生元素交换,说明数组已经有序,可以提前终止排序。
public class BubbleSort {
public static void main(String[] args) {
int[] arr = {4, 1, 3, 6, 2, 5};
bubbleSort(arr);
System.out.println(Arrays.toString(arr));
}public static void bubbleSort(int[] arr) {
boolean swapped;
for (int i = 1; i <= arr.length - 1; i++) {
swapped = false;
for (int j = 0; j < arr.length - i; j++) {
if (arr[j] > arr[j + 1]) {
swap(arr, j, j + 1);
swapped = true;
}
}
if (!swapped) {
break; // 如果没有发生交换,说明数组已经有序,提前终止排序
}
}
}public static void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
数组默认值:
Java虚拟机内存区域:
区域名称 | 作用 | 说明 |
---|---|---|
程序计数器(寄存器) | 是一块较小的内存区域,可以看做是当前线程执行的字节码的行号指示器 | 给CPU使用,和我们开发无关 |
虚拟机栈 | 虚拟机栈描述的是Java方法执行的内存模型 | JVM在使用操作系统功能的时候使用,和我们开发无关 |
堆 | 该区域的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存 | 是Java虚拟机所管理的内存中最大的一块,被进程的所有线程共享,在虚拟机启动时被创建 |
方法区 | 存放的是被虚拟机加载的class类信息,常量,静态变量,即时编译器编译后的代码等数据 | 方法区也是线程共享的 |
本地方法栈 | 与虚拟机栈类似,为虚拟机使用到的Native方法服务 | 方法运行时使用的内存,比如main方法运行,进入方法栈中执行 |
int[] arr = new int[3];
arr = null;
将arr设置为null意味着将arr引用的对象的引用设置为null,而不是清除其内存地址。
Arrays数组工具类:
方法 | 说明 |
---|---|
toString(Object[] a) | 将任意类型的数组的元素以字符串形式打印 |
deepToString(Object[] a) | 将任意类型的数组的深度元素以字符串形式打印(比如多维数组元素) |
asList(T... a) | 将任意类型数组转换为List集合形式 |
binarySearch(int[] a, int key) | 二分查找方法 |
sort(int[] a) | 数组排序 |
fill(int[] a, int fromIndex, int toIndex, int val) | 替换数组指定角标位置元素 |
copyOfRange(int[] original, int from, int to) | 对原数组进行指定范围元素复制为一个新数组 |
面向对象:
-
类:是一组具有类似属性和行为的集合。可以看成是一类事物的模板,使用事物的属性特征和行为特征来描述该类事物。
-
对象:是一类事物的具体体现。对象是类的一个实例(对象并不是找个女朋友),必然具备该类事物的属性和行为。
类与对象的关系:
-
类是对一类事物的描述,是抽象的。
-
对象是一类事物的实例,是具体的。
-
类是对象的模板,对象是类的实体。
public class Student {
// 成员变量
String username;//姓名
int age; //年龄//成员方法
//学习的方法
public static void study() {
System.out.println("好好学习,天天向上");
}
// 跑步的方法
public void run(String username,int distance) {
System.out.println(username+" 今天跑了"+distance+"m");
}
}
类名 对象名 = new 类名();
对象名.成员变量;
对象名.成员方法();
public class StudentTest {
public static void main(String[] args) {
// 创建对象格式:类名 对象名 = new 类名();
Student s = new Student();
System.out.println(s); //com.hopu.classobject.Student@15db9742
}
}
对象内存分析:![](https://img-blog.csdnimg.cn/4c71084203a04ad4889367898cb68275.png)
两个对象,调用同一方法内存图:![](https://img-blog.csdnimg.cn/55311185cf9b4af88a7bec8e66d155dd.png)
成员变量和局部变量:
-
在类中的位置不同
重点
-
成员变量:类中,方法外
-
局部变量:方法中或者方法声明上(形式参数)
-
-
作用范围不一样
重点
-
成员变量:类中
-
局部变量:方法中
-
-
初始化值的不同
重点
-
成员变量:有默认值
-
局部变量:没有默认值。必须先定义,赋值,最后使用
-
-
在内存中的位置不同
了解
-
成员变量:堆内存
-
局部变量:栈内存
-
-
生命周期不同
了解
-
成员变量:随着对象的创建而存在,随着对象的消失而消失
-
局部变量:随着方法的调用而存在,随着方法的调用完毕而消失
-
方法定义:
访问权限修饰符 静态修饰符 返回值类型 方法名(参数类型 参数名,参数类型 参数名...){
执行代码...
return 返回语句;
}
重载概念
方法重载:指在同一个类中,允许存在一个以上的同名方法,只要它们的参数列表不同即可,与修饰符和返回值类型无关。
- 多个方法在同一个类中
- 多个方法具有相同的方法名
- 多个方法的参数不相同,类型不同或者数量不同
注意:
- 参数列表:个数不同,数据类型不同,顺序不同。
- 重载方法调用:JVM通过方法的参数列表,调用不同的方法。
方法中的可变参数:
在实际开发过程中,有时方法中参数的个数是不确定,但是类型相同的。为了解决这个问题,在 J2SE 5.0 版本中引入了可变参数的概念。
getSum(int... v);
getOrder(String a,int... ids);
关于Java递归方法需要注意以下几点:
-
递归方法可以使用重复方法、少量代码,即可实现复杂功能的实现;
-
递归方法一定要有出口,否则无限递归调用,直到出现StackOverflowError(栈内存溢出)错误;
-
递归方法的递归次数也不能过多,否则同样出现StackOverflowError(栈内存溢出)错误;
-
递归方法都可以使用非递归方法解决,比如循环。
构造方法:
-
构造方法是类的一个特殊成员方法;
-
构造方法作用:(1)构造出来一个类的实例 (2)对构造出来个一个类的实例(对象)初始化;
-
构造方法的名字必须与定义他的类名完全相同,没有返回类型,甚至连void也没有;
-
类中必定有构造方法,若不写,系统自动提供一个无参构造方法;而一旦提供了有参构造方法,就不再提供默认的无参构造方法;
-
构造方法存在重载,比如无参构造方法和有参构造方法;
-
构造方法就是来创建对象的,使用new关键字,然后根据提供的构造方法进行选择构造即可。
static关键字:
定义静态变量
- 静态变量属于类,不属于对象。
- 可以直接通过类名来访问静态变量。
public class Demo {
static int num; //静态变量
int n; //非静态变量
public static void main(String[] args) {
n = 10; // 非法,需要实例
num = 20; // 通过类名访问静态变量
}
}
定义静态方法
- 静态方法属于类,不属于对象。
- 只能访问静态的变量和静态的方法,不能访问非静态的变量或方法。
- 通过类名调用静态方法。
public class Demo {
int n; // 非静态变量
static void method1() {
n = 10; // 非法,静态方法不能访问非静态变量
method2(); // 可以调用静态方法
}
static void method2() {
//....
}
}
Demo.method1(); //通过类名调用静态方法
静态初始化块
- 静态初始化块在类加载时执行一次。
- 用于初始化静态变量。
static {
num = 2;
}
单例模式
单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。
注意:
-
1、单例类只能有一个实例。
-
2、单例类必须自己创建自己的唯一实例。
-
3、单例类必须给所有其他对象提供这一实例。
关键代码:构造函数是私有的private。
1、懒汉式,线程不安全
public class Singleton { private static Singleton instance; private Singleton (){} public static Singleton getInstance() { if (instance == null) { instance = new Singleton(); // 创建对象是要消耗时间的 10s } return instance; } }
3、饿汉式
public class Singleton { private static Singleton instance = new Singleton(); private Singleton (){} public static Singleton getInstance() { return instance; } }
代码块 :
-
局部代码块
基本概念:局部位置,用于限定变量的生命周期,提高内存利用率。
-
静态代码块
基本概念:类中方法外,采用static修饰,用于对类进行初始化操作。
特点:只执行一次。
-
构造代码块
基本概念:类中方法外(成员位置),用"{}"括起来的java程序代码,每次在调用构造方法前,都会执行构造代码块,用于对对象进行初始化操作。
特点:每次创建对象,调用构造方法前都会执行。
-
构造方法
基本概念:用于对类进行初始化,创建对象。
特点:每次创建对象,都会执行一遍。
执行顺序是:静态代码块->构造代码块->构造方法。特点:静态代码块只执行一次,构造代码块在每次调用构造方法之前都会执行!
封装:
-
封装:主要是将类中的部分代码实现细节隐藏、封装起来,不直接对外提供访问;
-
继承:主要体现的父子类的关系上,提高了软件的可重用性和可扩展性;
-
多态:包括编译时多态和运行时多态,通过调用不同参数或名称的方法来决定父类对象动态调用哪个子类方法,增强了代码的灵活度。
封装的优点:
-
良好的封装能够减少耦合。
-
类内部的结构可以自由修改。
-
可以对类成员进行更精确的控制。
-
隐藏信息,实现细节。
封装基本使用:
-
使用
private
关键字来修饰类的成员(成员变量和成员方法)以及类。 -
对需要访问的成员变量,提供对应的一对public的 getXxx方法 、setXxx 方法。
-
private
修饰的成员方法,只允许本类中的其他方法调用; -
private
修饰的类,只能作为内部类使用(内部类后续详解)。
说明:
-
private是一个权限修饰符,代表最小权限(其他权限修饰符包括public、protected、default、private),只能在同一个类下访问。
封装的使用:
- private 数据类型 变量名;// 同时提供成员变量的getXxx、setXxx方法
- private 静态修饰符 返回值类型 方法名(参数列表){ 方法体 };
JavaBean:
JavaBean
是 Java语言编写类的一种标准规范。符合JavaBean
的类,要求类必须是具体的和公共的,并且具有无参数的构造方法,提供用来操作成员变量的set
和get
方法。
public class ClassName{
// 成员变量
// 构造方法
// 无参构造方法【必须】
// 有参构造方法【建议】
// 成员方法
// getXxx()
// setXxx()
}
访问权限修饰符:
-
public:公共的。
-
protected:受保护的。
-
default:默认的(默认什么都不用写)。
-
private:私有的。
继承:
继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。
继承语法:
// 父类
public class Animal {
private String name;
public void run() {
System.out.println("动物在奔跑");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
// 子类
public class Rabbit extends Animal {
// 打印一下名字
public void printName(String name) {
System.out.println("name=" + name);
}
}
// 测试类
public class ExtendsTest {
public static void main(String[] args) {
Rabbit r= new Rabbit();
// 通过父类方法为属性赋值
r.setName("小白兔");
// 调用从父类继承的方法
r.run();
// 调用本类方法
r.printName(r.getName());
}
}
继承的好处:
-
提高代码的复用性。
-
类与类之间产生了关系,是多态的前提。
继承后的特点:
成员变量重名:
子父类中出现了同名的成员变量时,在子类中需要访问父类中非私有成员变量时,需要使用 super 关键字,修饰父类成员变量,类似于之前学过的 this 。
成员方法不重名:
如果子类父类中出现不重名的成员方法,这时的调用是没有影响的。
调用方法时,先在子类中查找有没有对应的方法,若子类中存在就会执行子类中的方法,若子类中不存在就会执行父类中相应的方法。
成员方法重名:
如果子类父类中出现重名的成员方法,这时的访问是一种特殊情况,并且分为两种情况。
-
如果子类出现与父类重名方法,但是方法参数不同,这种情况属于方法重载;
-
如果子类出现与父类重名方法,同时方法参数也相同,这种情况叫做方法重写Override。
方法重写:
子类中出现与父类一模一样的方法时(方法名和参数列表都相同,重写的返回值类型相同或者是父类方法的子类),会出现覆盖效果,也称为重写或者复写。
注意事项:
-
子类方法覆盖父类方法,必须要保证权限大于等于父类权限。
-
子类方法覆盖父类方法,方法名和参数列表都要一模一样。
-
子类方法覆盖父类方法,返回值类型可以与父类保持一致,或者返回父类返回值的子类。
-
私有方法不是不能继承,而是无法访问,所以不能重写。