编译
源码文件通过 javac 编译, 然后在 Java 虚拟机上执行编译过的字节码,下面是具体步骤
User.java // 源码文件
javac User.java // 编译命令
User.class // 字节码
结构
.java 扩展名 是一个源文件.一个 .java
文件中只能有一个 public
类,这是 Java 语言的一个规则。如果一个类被声明为 public
,则文件名必须与该类的名字完全一致(区分大小写),并且文件扩展名必须为 .java
。
1 | // 文件名就是 Dog.java |
关于包(package)
package
语句必须是 Java 文件中的第一条语句(除非有注释或空行)。如果你在类中没有指定
package
,则该类属于默认包(default package),这意味着它没有明确的包名。默认包中的类无法被其他包中的类访问,因此在实际开发中,通常避免使用默认包。在同一个包中,文件名(即类名)必须是唯一的
1
2
3
4
5src
└── com
└── huangben
└── base
└── MyClass.java1
package com.huangben.base;
1
2
3
4
5
6
7
8
9
10
11
12
13// src/com/example/Main.java
package com.example;
import com.example.user.User;
import com.example.order.Order;
public class Main {
public static void main(String[] args) {
Order order = new Order("Order #1234");
User user = new User("Alice", order);
user.printUserOrder();
}
}
关于 main
方法
main
方法的签名1
public static void main(String[] args)
public
:表示这个方法可以被 Java 虚拟机(JVM)从任何地方调用。static
:表示该方法属于类本身,而不是类的实例,因此 JVM 不需要创建类的实例就可以调用它。void
:表示方法不返回任何值。String[] args
:用于接收命令行参数,是一个String
类型的数组
执行 main
方法
- 当你编译并运行这个文件时,你可以选择执行其中任何一个类的
main
方法。运行哪个类的main
方法取决于你在命令行中指定的类名。
例如:
1 | javac MainExample.java # 编译文件 |
总结
普通的 Java 应用程序: 必须有一个 main
方法,JVM 通过这个方法启动程序。
特殊类型的 Java 应用程序: 如 Applet、Servlet、JavaFX 应用程序或使用测试框架时,main
方法可能不是必需的,因为有其他的启动机制。
类与对象
对象是靠类的模型塑造出来的实例,包含实例变量和方法
java 是强类型语言,不管是对象,还是变量 、方法返回值、参数等都有类型
类和对象的区别
类不是对象,是用来创造对象的模型
对象的声明、创建、赋值
1 | Dog myDog = new Dog(); |
- 虚拟机分配空间给 引用变量 myDog 并且 固定类型为 Dog 类型
- 创建对象 new Dog()
- = 赋值
方法
- 方法必须声明返回类型,void 类型表示该方法不返回任何东西
- 如果方法返回不是 void 类型,就必须要返回一个和方法声明类型相同的值
使用 Java API 的步骤
- 导入包: 通过
import
语句导入需要使用的 Java API 类。 - 创建对象: 使用
new
关键字创建类的实例。 - 调用方法: 使用点操作符调用对象的方法或访问其属性。
1 | import java.util.ArrayList; |
继承与多态
1 | class Animal { |
总结
- 继承:子类可以继承父类的属性和方法,复用代码并扩展功能。
不会继承 private 类型的变量跟方法! - 多态:通过使用
@Override
来表示,同一个方法可以在不同的子类中表现出不同的行为,体现出灵活性和可扩展性。
方法可以覆盖,实例变量不行!
接口与抽象
我个人理解就是,有些类不能被实例化,它代表一种抽象的东西。例如,Animal 是抽象的, 狗是具体的,犬类是抽象的,猫是具体的。
设计目的
抽象类可以提供一些基本的功能(如构造函数、字段等),子类可以在此基础上扩展自己的功能,避免从头开始编写代码。
1 | abstract class Animal { |
构造器(构造函数)
自我理解
构造器就是在初始化对象,即 Dog mydog = new Dog()
时 ,Dog 类 中默认包含的一种特殊方法.
默认情况下一个类没有手动写出构造器,编译器会自动提供一个默认构造器 。实际上,new Dog()
这个动作其实就相当于调用了默认的构造函数,即 下面示例 public Dog() ,类中的实例变量是有初始值的。数值型为 0,布尔型为 false,对象引用为 null等
1 | class Dog { |
修饰符
构造器的访问修饰符可以是 public
、protected
、private
或默认(包私有)。
不同修饰符就是权限不一样,然后包私有的意思是说,默认的构造函数,不同包不可以调用,只能包内才可以实例化
例如:
1 | // 文件: Test.java |
调用父类构造器
super()
- 调用父类构造函数的唯一方法只能是执行
super()
- 子类构造器被调用时,它会隐式地自动调用父类的构造器,就是说当
public Dog()
被调用时,下面的 super()可以写,可以不写,如果带参数就必须写了
例如:
1 | class Dog extends Animal { |
this
如下代码
1 | class Student { |
当写 Student st1 = new Student("张三", 23);
时:
new Student("张三", 23)
这段代码会调用Student
类的构造函数来创建一个新的Student
对象。- 在这个构造函数执行的过程中,
this
就代表正在被创建的这个对象,也就是st1
。 - 所以,
this.name = name;
实际上是在说:“把传入的名字(比如 ‘张三’)赋值给st1
的name
属性。”
this 和 super 区别
代表当前对象:
this
代表当前对象st1
的实例,可以用来访问当前类的属性、方法,或者调用当前类的另一个构造函数。代表父类对象:
super
代表当前对象st1
的父类部分,可以用来访问父类的属性和方法,或者调用父类的构造函数。
重载
调用同类中的其他构造函数这个就是重载。
目的
在一个构造函数中使用 this
来调用同类中的另一个构造函数,从而避免重复代码。
代码示例
假设你有一个 Person
类,有多个构造函数
1 | class Person { |