Java入门 17 3\24
类的成员之四: 代码块(或初始化块)
- 代码块的作用:用来初始化类、对象。
- 代码块如果有修饰的话,只能使用static。
- 分类: 静态代码块 vs 非静态代码块
public class BlockTest
{
}
class Person
{
//属性
String name;
int age;
static String desc = "我是一个人";
//构造器
public Person()
{
}
public Person(String name, int age)
{
this.name = name;
this.age = age;
}
//代码块
{
}
//方法
public void eat
{
System.out.println("吃饭");
}
@Override
public String toString()
{
return "Person[name = " + name", age=" + age + "]"
}
}
- 静态代码块
- 内部可以有输出语句。
- 随着类的加载而执行。(只执行一次)
- 作用:初始化类的信息,对类中静态的属性重新赋值。
- 如果一个类中定义了多了静态代码块,则按照声明的先后顺序执行。
- 静态代码块的执行要优先于非静态代码的块的执行。(无关声明的先后)
- 只能调用静态结构(属性、方法), 不可以调用非静态结构。
//static的代码块
static
{
System.out.println{"hello,static block"};
desc = "我是一个爱学习的人”;
}
- 非静态代码块
- 内部可以有输出语句。
- 随着对象的创建而执行。(创建几个对象,就执行几次)
- 作用:可以在创建对象时进行初始化。
- 如果一个类中定义了多个非静态代码块,则按照声明的先后顺序执行。
- 可以调用非静态结构和静态结构。
Person p1 = new Person();
//非static代码块
{
System.out.println{"hello, block"};
age = 1;
}
总结: 由父及子,静态先行。
属性可以赋值的位置
- 默认初始化。
- 显式初始化。
- 构造器中初始化。
- 有了对象以后,可以通过“ 对象.属性“ 或 ” 对象.方法 “ 的方式,进行赋值。
- 在代码块中赋值。(代码块要在构造器之前执行)
执行顺序: 默认 — > 显式/代码块(它们两个看谁先写,先写的先执行) ----> 构造器 —> 调用的方法赋值
关键字:final(最终的)
-
final可以用来修饰的结构 :类、方法、变量。
-
final用来修饰一个类、(太监类)。
此类不能被其他类所继承。
eg:String类、System类、StringBuffer类。
-
final 用来修饰方法:表明此方法不可以被重写。
比如:Object 类中 getClass( ) ;
-
final用来修饰一个变量:此时的 “变量“ 就称为是一个常量。 final int num = 10;
-
final修饰属性:可以考虑赋值的位置有:显式初始化、代码块中赋值、在构造器中初始化。(方法和调用都不可以,因为在new的时候已经有了内存。)
-
final修饰局部变量:普通变量:不能修改。
特别的:final修饰形参时:在调用时直接赋值,一旦赋值以后,方法中不可修改,也不可赋值,只能调用。
-
-
static final 用来修饰:
- 只能修饰 属性、 方法。
- 用来修饰属性:全局常量。
- 用来修饰方法:方法可以通过类来调用,且不能被重写。
抽象类与抽象方法
抽象就是不可以实例化。
abstract关键字的使用
-
abstract: 抽象的。
-
abstract可以用来修饰的结构:类、方法。
Public class AvstractTest{ public static void main(Strnig[] agrs){ // 一旦Person类抽象了,就不可实例化。 //Person p1 = new Person; //p1.eat(); } } class Person{ String name; int age; public Person(){ } public Person(String name, int age){ this.name = name; this.age = age; } public void eat{ System.out.println("人吃饭"); } public void walk(){ System.out.println("人走路"); } } class Student extends Person{ }
abstract修饰类: 抽象类
- 此类不能实例化。
- 抽象类中一定有构造器,便于子类实例化时调用。(涉及,子类对象实例化全过程)
- 开发中,都会提供抽象类的子类,让子类对象实例化,完成相关的操作。
abstract修饰方法:抽象方法
-
抽象方法只有方法的声明,没有方法体。
-
包含抽象方法的类一定是抽象类,(为了保证不被实例化的对象调用,必须保证无法实例化)
反之,抽象类中可以没有抽象方法。
-
若子类重写了父类中所有的抽象方法后,此子类方可实例化、反之没有重写,则子类也是抽象类,需要用abstract修饰类。
abstract class Person{
//不是抽象方法。
public void eat(){
}
//是抽象方法。
public abstract void eat();
}
abstract使用上的注意点:
- abstract不能用来修饰:属性、构造器等结构。
- abstract不能用来修饰私有方法、静态方法、final的方法、final的类。(因为私有方法不能被重写)
例题
编写一个Employee类,声明为抽象类,包含如下三个属性:name,id,salary。提供必要的构造器和抽象方法,work()。
public class Employee{
private String name;
private int id;
private double salary;
public Employee(){
super();
}
public Employee(String name,int id, double salary){
super();
this.name = name;
this.id = id;
this.salary = salary;
}
public abstract void work();
}
抽象类的匿名子类
public class PersonTest{
public static void main(String[] args){
method(new Student()); // 匿名对象
Worker worker = new Worker();
method(worker)//非匿名类的非匿名的对象
method(new Worker());//非匿名的类匿名对象
}
//创建了一匿名子类的对象,p
//Person类是当前创造对象的,父类,将抽象/父类中的方法进行了重写,并且直接实例化了一个对象为p。
Person p = new Person(){
@Override
public void eat(){
System.out.println("吃东西");
}
}
method(p);
//也可以直接这么书写
method(new Person(){
@Override
public void eat(){
System.out.println("吃东西");
}
});
public static void method (Student s){
}
}
抽象类的应用:模板方法设计模式(TemplateMethod)