标签:对象 子类 void 修饰符 面向对象 方法 public
类的组成
组成部分 |
描述 |
类声明 |
定义类的名称、访问修饰符和继承关系(如extends 、implements ) |
成员变量 |
类中的变量,用于存储对象的状态。可以是实例变量或静态变量 |
构造方法 |
用于创建类的对象并初始化对象的状态。可以有多个构造方法(重载) |
成员方法 |
类中的方法,用于定义对象的行为。可以是实例方法或静态方法 |
代码块 |
静态代码块(static {} )或实例代码块({} ),用于在类加载或对象创建时执行代码 |
内部类 |
定义在类内部的类,可以是静态内部类或非静态内部类 |
权限修饰符 |
控制类、方法、字段的访问权限,如public 、private 等 |
其他修饰符 |
如final 、abstract 、static 等,用于进一步定义类的特性 |
成员变量
局部变量和成员变量区别
特性 |
局部变量 |
成员变量 |
定义位置 |
方法、构造函数或代码块内部 |
类的内部,方法外部 |
作用域 |
仅限于定义它的方法、构造函数或代码块 |
整个类中都可以访问 |
生命周期 |
随方法的调用或代码块的执行而创建,执行结束后销毁 |
随对象的创建而创建,随对象的销毁而销毁 |
默认值 |
无默认值,必须显式初始化 |
有默认值 |
访问修饰符 |
不能使用访问修饰符(如 public 、private ) |
可以使用访问修饰符 |
存储位置 |
栈内存 |
堆内存(对象实例中) |
是否属于对象 |
不属于对象,仅属于方法或代码块 |
属于对象,是对象的一部分 |
成员变量的默认值
数据类型 |
默认值 |
byte |
0 |
short |
0 |
int |
0 |
long |
0L |
float |
0.0f |
double |
0.0d |
char |
'\u0000' (空字符) |
boolean |
false |
引用类型(如 String 、Object ) |
null |
内存分析
public class Person {
int id;
int age;
public static void main(String[] args) {
Person p1 = new Person();
System.out.println(p1.age); // 0
}
}
public class Person {
int id;
int age;
String school;
public Person(int a, int b, String c) {
id = a;
age = b;
school = c;
}
public static void main(String[] args) {
Person p = new Person(1, 20, "数加");
}
}
步骤
- main方法作为程序的入口:在栈中开辟main方法栈帧
- 第一次遇到Person:在方法区中加载
Person.class
字节码信息
- new关键字出现:参照字节码信息在堆中创建对象,并给对象的属性做初始化操作(赋予默认值0、0、null)
- 调用有参构造方法Person(1, 20, "数加")进行形参的传递:在栈中开辟构造方法Person()栈帧,局部变量a、b、c先进后出,a和b直接赋值1和20,第一次遇到字符串
"数加"
时,会将其放入方法区中的字符串常量池,再将地址值传给c
- 有参构造方法内部的赋值操作:将a、b、c的值分别赋给id、age、school,其中c是将地址值赋给了school,school通过该地址值可以访问字符串常量池中对应的字符串,此时,有参构造方法被调用执行完毕,对应的栈帧被回收
- Person p = new Person(1, 20, "数加"):将堆中创建对象的地址值赋给p
代码块
代码块类型 |
定义 |
作用 |
特点 |
执行顺序 |
普通代码块 |
在方法或语句中定义的代码块。 |
限制变量的作用范围,增强代码可读性。 |
- 代码块中定义的变量只在块内有效。 - 代码块执行完毕后,变量会被销毁。 |
在方法调用时按顺序执行。 |
实例初始化块 |
在类中直接定义的代码块,没有名称。 |
用于初始化实例变量,每次创建对象时都会执行。 |
- 在构造函数之前执行。 - 可以有多个实例初始化块,按顺序执行。 |
在构造函数之前执行。 |
静态初始化块 |
在类中定义的静态代码块,用 static 关键字修饰。 |
用于初始化静态变量,在类加载时执行。 |
- 只执行一次,无论创建多少个对象。 - 可以有多个静态初始化块,按顺序执行。 |
在类加载时执行,且只执行一次。 |
修饰符
权限修饰符
修饰符 |
同类 |
同包 |
不同包子类 |
不同包 |
描述 |
public |
✔️ |
✔️ |
✔️ |
✔️ |
公共访问权限,任何类都可以访问。 |
protected |
✔️ |
✔️ |
✔️ |
❌ |
受保护访问权限,允许子类及同包中的类访问。 |
default (无修饰符) |
✔️ |
✔️ |
❌ |
❌ |
默认访问权限,仅允许同包中的类访问。 |
private |
✔️ |
❌ |
❌ |
❌ |
私有访问权限,仅允许同类中的成员访问。 |
一般来说,属性用private修饰,方法用public修饰。
static修饰符
修饰对象 |
作用 |
示例 |
使用场景 |
变量 |
变量属于类,而非实例(类方法) |
static int count = 0; |
定义类级别的共享数据,如计数器、配置项等。 |
方法 |
方法属于类,可通过类名直接调用(类变量) |
static void printMessage() {} |
定义工具方法或不需要实例化的方法。 |
代码块 |
类加载时执行,用于初始化静态变量 |
static { System.out.println("Static block"); } |
初始化静态变量或执行类加载时的操作。 |
内部类 |
内部类属于类,而非实例 |
static class NestedClass {} |
定义与外部类实例无关的嵌套类。 |
static内存分析
final修饰符
修饰对象 |
作用 |
示例 |
使用场景 |
类 |
类不能被继承 |
final class MyClass {} |
防止类被扩展,确保类的行为不被修改。如Java 中的 String 类就是 final 类,以确保其不可变性。 |
方法 |
方法不能被重写 |
final void myMethod() {} |
防止子类修改方法的行为,确保方法一致性。某些核心算法或工具方法可以声明为 final 。 |
变量 |
变量只能赋值一次(常量) |
final int x = 10; |
定义常量值,确保变量的值不被修改。 |
参数 |
参数在方法内部不能被修改 |
void myMethod(final int param) {} |
防止方法内部意外修改参数值,增强安全性。 |
abstract修饰符
修饰对象 |
作用 |
示例 |
使用场景 |
类 |
类不能被实例化,只能被继承 |
abstract class Animal {} |
定义父类,要求子类实现具体行为。 |
方法 |
方法没有方法体,必须由子类重写 |
abstract void makeSound(); |
定义方法规范,要求子类提供具体实现。 |
static、final、abstract的区别
特性 |
final |
static |
abstract |
修饰对象 |
类、方法、变量、参数 |
变量、方法、代码块、内部类 |
类、方法 |
作用 |
表示不可改变 |
表示类级别,而非实例级别 |
表示未实现,需要子类完成 |
类的特点 |
类不能被继承 |
类不能被直接实例化,成员属于类 |
类不能被实例化,只能被继承 |
方法的特点 |
方法不能被重写 |
方法属于类,可直接通过类名调用 |
方法没有实现,必须由子类重写 |
变量的特点 |
变量只能赋值一次(常量) |
变量属于类,所有实例共享 |
不能修饰变量 |
使用场景 |
防止类被继承、方法被重写、变量被修改 |
定义工具方法、共享数据、静态初始化 |
定义父类、规范子类行为 |
封装
继承
多态
JAVA是一种强类型语言,在定义形参时需要声明每一个参数的数据类型,如果形参过多,但这些形参类型都有一个共同的父类,那么在形参列表中可以只声明一个父类类型的变量,而传递的实际参数既可以是父类类型的对象,也可以是不同子类类型的对象。当传递子类对象时,方法内部调用的方法即为该子类对象对父类重写后的方法,这样一来,后续添加新的子类或修改子类的方法时,就无需再修改该方法内部的代码,只需将子类对象作为实参进行传递即可!
实现方式:类、抽象类、接口
特性 |
类 (Class) |
抽象类 (Abstract Class) |
接口 (Interface) |
定义 |
使用 class 关键字定义 |
使用 abstract class 关键字定义 |
使用 interface 关键字定义 |
实例化 |
可以直接实例化 |
不能直接实例化,必须通过子类实例化 |
不能直接实例化,必须通过实现类实例化 |
多态实现 |
通过继承和方法重写实现多态 |
通过继承和方法重写实现多态 |
通过实现接口和方法重写实现多态 |
方法实现 |
可以提供具体方法实现 |
可以提供具体方法实现,也可以有抽象方法 |
只能有抽象方法(Java 8 后可以有默认方法) |
字段 |
可以有实例字段和静态字段 |
可以有实例字段和静态字段 |
只能有静态常量(public static final ) |
继承 |
单继承,只能继承一个类 |
单继承,只能继承一个类 |
多继承,可以实现多个接口 |
构造器 |
可以有构造方法 |
可以有构造方法 |
不能有构造方法 |
权限修饰符 |
可以使用任意访问修饰符,但private和protected只能修饰内部类 |
可以使用任意访问修饰符,但private和protected只能修饰内部类 |
默认 public ,可以使用任意访问修饰符,但private和protected只能修饰内部接口 |
设计目的 |
用于创建对象和实现具体逻辑 |
用于部分实现,要求子类完成剩余逻辑 |
用于定义行为契约,要求实现类完成逻辑 |
形参及返回值问题
形参
形参类型 |
传入参数 |
父类 |
父类对象或其子类对象 |
抽象类 |
抽象类的具体子类对象 |
接口 |
接口的实现类对象即实现该接口的具体对象 |
返回值
返回值类型 |
返回值 |
父类 |
父类对象或其子类对象 |
抽象类 |
抽象类的具体子类对象 |
接口 |
接口的实现类对象即实现该接口的具体对象 |
内部类
成员内部类
局部内部类
匿名内部类
格式
new 类名或者接口名() {
重写方法;
};
切记:匿名内部类不是一个类而是一个对象,是一个子类或实现类对父类或接口进行重写后没有进行命名,只保留了方法体,再加上父类名或接口名来进行该匿名类对象的创建,是一种代码的简化写法。
普通写法
以接口为例:单独写一个实现类---主程序中创建一个实现类对象---通过该对象调用方法
interface Swim {
public abstract void swimming();
}
// 1. 定义接口的实现类
class Student implements Swim {
// 2. 重写抽象方法
@Override
public void swimming() {
System.out.println("狗刨式...");
}
}
public class Test {
public static void main(String[] args) {
// 3. 创建实现类对象
Student s = new Student();
// 4. 调用方法
s.swimming();
}
}
匿名内部类写法
以接口为例:直接写成匿名内部类形式(相当于创建了一个实现类对象)---直接通过该对象调用方法/使用接口的引用来接收该对象(多态)再进行方法的调用
interface Swim {
public abstract void swimming();
}
public class Demo07 {
public static void main(String[] args) {
// 使用匿名内部类
new Swim() {
@Override
public void swimming() {
System.out.println("自由泳...");
}
}.swimming();
// 接口 变量 = new 实现类(); // 多态,走子类的重写方法
Swim s2 = new Swim() {
@Override
public void swimming() {
System.out.println("蛙泳...");
}
};
s2.swimming();
s2.swimming();
}
}
应用场景
匿名内部类本身就是一个对象,当方法的形参类型是抽象类或接口时,可以直接作为参数传入该方法。
interface Swim {
public abstract void swimming();
}
public class Demo {
public static void main(String[] args) {
// 匿名内部类作为方法参数传递
Swim s3 = new Swim() {
@Override
public void swimming() {
System.out.println("蝶泳...");
}
};
// 传入匿名内部类
goSwimming(s3);
// 完美方案: 一步到位
goSwimming(new Swim() {
public void swimming() {
System.out.println("大学生, 蛙泳...");
}
});
goSwimming(new Swim() {
public void swimming() {
System.out.println("小学生, 自由泳...");
}
});
}
// 定义一个方法,模拟请一些人去游泳
public static void goSwimming(Swim s) {
s.swimming();
}
}
标签:对象,
子类,
void,
修饰符,
面向对象,
方法,
public
From: https://www.cnblogs.com/wy56297/p/18678531