java定义类的初始化块,Java面向对象--代码块(初始化块)和内部类(示例代码)

本篇博客介绍Java学习过程中类的成员之代码块(初始化块)和内部类的具体使用。

目录:

? 代码块(初始化块)

代码块的概述

? 代码块(或初始化块)的作用:对Java类或对象进行初始化操作

? 代码块(或初始化块)的分类:一个类中代码块只能被static修饰符修饰,若由static修饰称为静态代码块(static block),没有使用static修饰的,为非静态代码块

? static 代码块化 通常用于初始化static

class Person{

public static String nation;

static{

nation = "China";

}

}

静态代码块:用static修饰的代码块

? 可以有输出语句

? 可以对类的属性、类的声明进行初始化操作

? 不可以对非静态的属性初始化。即:不可以调用非静态的属性和方法。

? 若有多个静态的代码块,那么按照从上到下的顺序依次执行。

? 静态代码块的执行要先于非静态代码块。

? 静态代码块随着类的加载而执行,且只执行一次。

静态代码块:用static修饰的代码块

? 可以有输出语句。

? 可以对类的属性、类的声明进行初始化操作。

? 除了调用非静态的结构外,还可以调用静态的变量或方法。

? 若有多个非静态的代码块,那么按照从上到下的顺序依次执行。

? 随着对象的创建而执行,创建一次执行一次。且先于构造器执行。

public class BlockTest {

public static void main(String[] args) {

String desc = Person.desc;

System.out.println("index:" + Person.index);

System.out.println("index:" + Person.index);

Person person = new Person();

System.out.println("index:" + Person.index);

Person person = new Person();

System.out.println("index:" + Person.index);

System.out.println(person.toString());

}

}

class Person{

//属性

static String name;

int age;

static int index = 10;

static String desc = "人类";

//构造器

public Person() { }

//非静态代码块

{

age = 19; //可以使用静态属性和非静态属性

name = "张三";

index++;

System.out.println("not static block");

getInfo(); //可以调非静态方法和静态方法

eat();

}

//静态代码块

static {

// age = 20; 不能使用非静态变量

name = "李四";

index++;

System.out.println("static block");

getInfo();

// eat(); 不能使用非静态方法

}

//方法

public void eat() {

System.out.println("吃饭");

}

public static void getInfo() {

System.out.println("我是一个快乐的人");

}

@Override

public String toString() {

return "Person [name=" + name + ", age=" + age + "]";

}

}

/*输出和说明

static block //静态代码块随着类的加载而执行,只执行一次

我是一个快乐的人

index11

index11

not static block //随着对象的创建而执行

我是一个快乐的人

吃饭

index12

not static block //创建一个对象执行一次

我是一个快乐的人

吃饭

index13

Person [name=张三, age=19] //非静态的代码块晚于静态代码执行

*/

程序中成员变量赋值的执行顺序

20200320195040073368.png

? 内部类(Inner class)

内部类概述

? 内部类是Java的五大成员之一,当一个事物的内部,还有一个部分需要一个完整的结构进行描述,而这个内部的完整的结构又只为外部事物提供服务,那么整个内部的完整结构最好使用内部类。

? 在Java中,允许一个类的定义位于另一个类的内部,前者称为内部类,后者称为外部类。

? Inner class一般用在定义它的类或语句块之内,在外部引用它时必须给出完整的名称。

? Inner class的名字不能与包含它的外部类类名相同。

? 内部类可分为成员内部类(static成员内部类和非static成员内部类)以及局部内部类(不谈修饰符)、匿名内部类

成员内部类

class 外部类{

//成员变量声明

//成员方法声明

//构造器声明

class 成员内部类{

}

}

? 可以将成员内部类看成外部类的成员(类似一个成员方法)或者是外部类中的一个类,同时具有成员和类的部分特性。

? 和外部类(只能声明为public 或者省略默认)不同,Inner class还可以声明为private或protected;

? 可以调用外部类的结构

? Inner class 可以声明为static的,但此时就不能再使用外层类的非static的成员变量;

? 可以在内部定义属性、方法、构造器等结构

? 可以声明为abstract类 ,因此可以被其它的内部类继承

? 可以声明为final的

? 编译以后生成OuterClass$InnerClass.class字节码文件(也适用于局部内部类)

注意:

? 非static的成员内部类中的成员不能声明为static的,只有在外部类或static的成员内部类中才可声明static成员

? 外部类访问成员内部类的成员,需要“内部类.成员”或“内部类对象.成员”的方式

? 成员内部类可以直接使用外部类的所有成员,包括私有的数据

? 当想要在外部类的静态成员部分使用内部类时,可以考虑内部类声明为静态的

局部内部类

//声明局部内部类

class 外部类{

//声明在方法体中

方法(){

class 局部内部类1{

}

}

//声明在代码块内

{

class 局部内部类2{

}

}

//声明在构造器中

public 外部类名(){

class 局部内部类3{

}

}

}

? 只能在声明它的方法或代码块中使用,而且是先声明后使用。除此之外的任何地方

都不能使用该类

? 但是它的对象可以通过外部方法的返回值返回使用,返回值类型只能是局部内部类的父类或父接口类型

public class InnerClassTest{

//开发中很少使用

public void method(){

//局部内部类

class AA{

//....

}

}

//常见使用方式

//返回了一个实现了Comparable节后的类的对象

public Comparable getComparable(){

//创建一个实现了Comparable接口的类:局部内部类

class MyComparable implements Comparable{

@Override

public int compareTo(Object o){

//....

return 0;

}

}

return new MyComparable();

}

}

局部内部类特点:

? 内部类仍然是一个独立的类,在编译之后内部类会被编译成独立的.class文件,但是前面冠以外部类的类名和(符号,如:Person)PetDog.class ,局部内部类还会加上数字编号,如:Person$1AA.class。

? 只能在声明它的方法或代码块中使用,而且是先声明后使用。除此之外的任何地方都不能使用该类。

? 局部内部类可以使用外部类的成员,包括私有的。

? 局部内部类可以使用外部方法的局部变量,但是必须是final的,jdk7之前必须声明final关键字,jdk之8之后可以省略final关键字,但是一旦在局部类中使用了该变量,系统就会默认该变量为final的。由局部内部类和局部变量的声明周期不同所致。常用于Android开发。

static void method1(){

int num1= 1;

//num1++; 报错

class BB{

int a = 1;

public int add() {

//jdk7之前必须将num1定义为final的,否则编译不通过,jdk8之后会默认为final

num1 = 10;

a += num1;

return a;

}

}

//num1 ++; 报错

//二选一,如果在内部类之后使用,内部类就不能使用,

//内部类中一旦使用就会默认该变量为final的,之后就不可以修改了

}

? 局部内部类和局部变量地位类似,不能使用public,protected,default,private

? 局部内部类不能使用static修饰,因此也不能包含静态成员

内部类的使用

创建成员内部了的实例化对象:

//创建静态成员内部类实例

外部类.内部类 变量名 = new 外部类.内部类构造器(参数列表);

OutClass.InnerClass o1 = new OutClass.InnerClass();

//创建非静态成员内部类实例

外部类 外部类对象变量名 = new 外部类构造器(参数列表);

OutClass out = new OutClass();

外部类.内部类 变量名 = 外部类对象变量名.new 内部类构造器(参数列表);

OutClass.InnerClass o2 = out.new InnerClass();

内部类调用成员:

? 如果内部类与外部类成员不重名直接调用,但是要注意static关键字的限制

? 如果内部类与外部类成员重名了,则直接使用变量名/方法名调用的是内部类方法中的局部变量,若没有局部变量效果相当于this.变量名/this.方法名,调用的是内部类的成员

? 如果调用外部类的成员,对于外部类的静态成员使用外部类.成员名方式调用,对于非静态外部类成员,使用外部类.this.成员名的方式调用

匿名内部类

? 匿名内部类不能定义任何静态成员、方法和类,只能创建匿名内部类的一个实例。一个匿名内部类一定是在new的后面,用其隐含实现一个接口或实现一个类。

? 格式:

new 父类构造器(实参列表)or 实现接口(){

// 匿名内部类的类体部分

}

匿名内部类特点:

? 匿名内部类必须继承父类或实现接口

? 匿名内部类只能有一个对象

? 匿名内部类对象只能使用多态形式引用

public class InnerClassTest{

匿名内部类(实现了Comparable接口),并将对象方法

public Comparable getComparable(){

//创建一个实现了Comparable接口的类:局部内部类

return new Comparable() {

@Override

public int compareTo(Object o){

//....

return 0;

}

};

}

}

本博客与CSDN博客???君?纤???同步发布

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值