普通语句块
语法:
{
}
注意:
1、普通语句块可以放置在类中与方法同级,也可以放置在方法中。
2、语句块依赖实例,而且语句块优先于类的构造方法。
3、普通的语句块放置的时候,是需要顺序的。它是放置在成员变量的下方。
4、语句块可以任意调用类中成员变量,或者方法。
静态语句块
语法:
static{
}
注意:
1、静态语句块的优先级要高于普通的语句块
2、静态语句块和成员变量的 顺序也是有关系的,如果要使用成员变量,则必须将其放置在成员变量的下方。
3、静态语句块访问的成员变量也必须是静态的成员变量
4、静态语句块访问的方法也必须是静态的方法
5、static修饰语句块不依赖实例,在调用main入口函数时,先执行静态语句块
6、static它是存储在内存中,static修饰静态语句块在类中只执行一次。
内部类
什么是内部类
将一个类A定义在另一个类B里面,里面的那个类A就称为内部类,B则称为外部类。
成员内部类
成员内部类 :定义在类中方法外的类。
定义格式:
class 外部类 {
class 内部类{
}
}
在描述事物时,若一个事物内部还包含其他事物,就可以使用内部类这种结构。比如,汽车类 Car 中包含发动机类 Engine ,这时Engine就可以使用内部类来描述,定义在成员位置。
代码举例:
class Car { //外部类
class Engine { //内部类
}
}
访问特点
1. 内部类可以直接访问外部类的成员,包括私有成员。
2. 外部类要访问内部类的成员,必须要建立内部类的对象。
创建内部类对象格式:
外部类名.内部类名 对象名 = new 外部类型().new 内部类型();
访问演示,代码如下:
定义类:
public class Car {
private boolean start = true;
//成员内部类: 可以调用外部的成员变量或成员方法
class Engine{
public void run() {
//直接访问外部类成员
if (start) {
System.out.println("车辆已经启动");
} else {
System.out.println("车辆停止");
}
}
}
public boolean isStart() {
return start;
}
public void setStart(boolean start) {
this.start= start;
}
//外部类不能直接调用,需要得到内部类的实例
}
定义测试类:
public class Main{
public static void main(String[] args) {
// 创建外部类对象
Car car = new Car();
// 创建内部类对象
Engine engine = car.new Engine();
// 调用内部类方法
engine.run();
// 调用外部类方法
car.setStart(false);
// 调用内部类方法
engine.run();
}
}
注意:内部类仍然是一个独立的类,在编译之后会内部类会被编译成独立的 .class文件,但是前面冠以外部类的类名和 符 号 。 比 如 : C a r 符号。 比如: Car 符号。比如:CarEngine.class
匿名内部类
匿名内部类:是内部类的简化写法。它的本质是一个带具体实现的父类或者父接口的匿名的子类对象。
开发中,最常用到的内部类就是匿名内部类了。以接口举例,当你使用一个接口时,似乎得做如下几步操作,
- 定义子类
- 重写接口中的方法
- 创建子类对象
- 调用重写后的方法
我们的目的,最终只是为了调用方法,那么能不能简化一下,把以上四步合成一步呢?匿名内部类就是做这样的快捷方式。
前提
匿名内部类必须继承一个父类或者实现一个父接口。
语法格式:
new 父类名或者接口名(){
// 方法重写
@Override
public void method() {
// 执行语句
}
};
使用方式
以接口为例,匿名内部类的使用,代码如下:
定义接口:
public interface FatherInner {
public default void eat(){
System.out.println("--普通方法--");
}
}
创建匿名内部类,并调用:
public class InnerTest {
public static void main(String[] args) {
/*
* 1.等号右边:是匿名内部类,定义并创建该接口的子类对象
* 2.等号左边:是多态赋值,接口类型引用指向子类对象
*/
FatherInner fatherInner = new FatherInner() {
@Override
public void eat() {
System.out.println("--匿名内部类调用一下--");
}
};
//调用eat方法,执行重写后的方法
fatherInner.eat();
}
}
通常在方法的形式参数是接口或者抽象类时,也可以将匿名内部类作为参数传递。代码如下:
public class InnerTest {
public static void main(String[] args) {
/*
* 1.等号右边:是匿名内部类,定义并创建该接口的子类对象
* 2.等号左边:是多态赋值,接口类型引用指向子类对象
*/
FatherInner fatherInner = new FatherInner() {
@Override
public void eat() {
System.out.println("--匿名内部类调用一下--");
}
};
//调用eat方法,执行重写后的方法
// fatherInner.eat();
studyEat(fatherInner);
}
public static void studyEat(FatherInner fi){
fi.eat();
}
}
以上两步,也可以简化为一步,代码如下:
public class InnerTest {
public static void main(String[] args) {
studyEat(new FatherInner(){
@Override
public void eat() {
// TODO Auto-generated method stub
FatherInner.super.eat();
}
});
}
public static void studyEat(FatherInner fi){
fi.eat();
}
}
静态内部类
public class Example03 {
static int b = 10;
//静态的内部类:访问外部类的成员或方法时需要定义为静态的成员或静态的方法
static class Example04{
int a = 20;
public Example04(){
}
public static void test01(){
System.out.println(b);
}
}
}
调用方式:
//静态内部类调用的方式
Example03.Example04 ex04 = new Example03.Example04();
ex04.test01();
Example03.Example04.test01();
局部内部类
public class Example05 {
public void test05(){
int a = 10;
//局部内部类
class Example06{
class Example07{
}
public void test06(){
System.out.println(a);
}
}
/**
* 局部内部类是在类的方法内部定义的类。局部内部类只能在方
* 法内部中使用。一旦方法执行完毕,局部内部类就会从内存中被清除。
*/
Example06 ex06 = new Example06();
ex06.test06();
}
}
调用方式:
//局部内部类的调用方式 – 不能在外部调用
Example05 ex05 = new Example05();
ex05.test05();
**
外部类
**
public class Example01 {
}
/**
* 类 等价于新建一个 Example02.java文件
* 在一个类的文件中只能有一个public关键字修饰类
* @author admin
*
*/
class Example02 extends Example01{
public static void main(String[] args) {
}
}