Java核心 -- 基本程序设计结构

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

// --------------对比结论-------------- // 

结论:父类变量引用子类实例时,按继承链优先执行子类中的方法

访问控制修饰符

猜你喜欢

转载自blog.csdn.net/WalleIT/article/details/87457074