Java核心 -- 基本程序设计结构
程序员文章站
2022-07-12 18:36:43
...
final关键字
- 修饰变量:关键字final修饰变量,表示这个变量只能被赋值一次,一旦被赋值之后,就不能再更改了,即final修饰变量时,是用来定义常量的,常量名应该全大写。例如如下代码:
final double PI = 3.14;
PI = 24.1; // error: cannot assign a value to variable 'PI'
- 修饰方法:可被子类继承,但是不能被子类覆盖
- 修饰类:不需要被继承,(final类的所有方法自动地成为final方法,但是类中域不会自动变成final)
命令行参数
每一个Java应用程序都有一个带String args[ ]参数的main方法,这个参数表明main方法将接收一个字符串数组,也就是命令行参数。例如
public class Test {
public static void main (String[] args) {
System.out.println("1" + args[0]);
System.out.println("2" + args[1]);
System.out.println("3" + args[2]);
}
}
// 编译上述源码后,在终端输入一下指令
java Test hi my world
// 运行结果
1hi
2my
3world
无参数的构造器
仅当类没有提供任何构造器的时候,系统才会提供一个默认的不带参数的构造器,如果在编写类的时候,编写了一个构造器,哪怕是很简单的,要想让这个类的用户能够采用new ClassName()的方式构造实例,就必须提供一个默认的不带参数的构造器。
初始化块
- 对象初始化块,第一次构造了类的实例,该初始化块就被会执行;
- 静态初始化块,虚拟机第一次加载该类,该初始化就会被执行;
// 不创建类实例,只会执行静态初始化块,不执行对象初始化块
public class Test {
// object initialization block
{
System.out.println(" object initialization block");
}
// static initialization block
static {
System.out.println(" static initialization block");
}
public static void main (String[] args) {
}
}
输出为:static initialization block
// 创建类实例情境下,先执行静态初始化块(因为类先被加载),再在构造实例时执行对象初始化块
public class Test {
// object initialization block
{
System.out.println(" object initialization block");
}
// static initialization block
static {
System.out.println(" static initialization block");
}
public static void main (String[] args) {
new Test();
}
}
输出为:
static initialization block
object initialization block
抽象类
-
包含一个或多个抽象方法的类本身必须被声明为抽象的;
-
抽象方法,不能有方法体:Abstract methods cannot have a body;
- 抽象类不能被实例化,但是可以定义一个抽象类的对象变量,只是它只能引用非抽象子类的对象。例如,
// 抽象父类Person
public abstract class Person {
}
// 子类Student
public class Student extends Person {
public static void main (String[] args) {
new Person(); // error:Person is abstract, cannot be instantiated
Person p = new Student(); // OK: 这里是正确的,p是一个抽象类Person的变量,Person引用了一个非抽象子类Student的对象
}
}
- 如上所述,抽象类变量可以引用非抽象子类的实例,并且可以通过该变量访问该引用子类的方法,如
// 抽象父类 Person 声明了抽象方法saying()
public abstract class Person {
public abstract void saying();
}
// 非抽象子类 Student 继承Person 并实现父类中声明的抽象方法saying()
public class Student extends Person {
public static void main (String[] args) {
Person p = new Student();
p.saying(); // 虽然Person中没有定义saying的具体实现,但是由于其引用的是子类实例,所以调用的子类的方法,
// 但是是否可以省略Person父类中的抽象方法saying呢?
// 答案是不行,因为编译器只允许调用类中声明的方法,Person中如何没有声明该方法,即便是引用的是子类实例,也不能调用子类中独有的方法
}
public void saying() {
System.out.println("Hello world");
}
}
- 在正常的类继承中,对上述情境进行试验:父类变量引用子类实例时,按继承链优先执行子类中的方法
public class Person {
public void saying(){
System.out.println("Person Hello world");
}
}
//-------------------- Student 子类中覆盖父类的saying方法 ----------------------------//
public class Student extends Person {
public static void main (String[] args) {
Person p = new Student();
p.saying();
}
public void saying() {
System.out.println(" Student Hello world");
}
}
输出结果为:Student Hello world
//-------------------- Student 子类中正常继承父类的saying方法 ----------------------------//
public class Student extends Person {
public static void main (String[] args) {
Person p = new Student();
p.saying();
}
}
输出结果为:Person Hello world
// --------------对比结论-------------- //
结论:父类变量引用子类实例时,按继承链优先执行子类中的方法
访问控制修饰符
下一篇: 5.程序循环结构