【JavaSE】面向对象——代码块和内部类

86 阅读4分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第1天,点击查看活动详情


学习面向对象的三条主线

  1. Java类及类的成员:属性,方法,构造器; 代码块、内部类
  2. 面向对象的三大特征:封装、继承、多态,(抽象性)
  3. 其他关键字:this,super,static,final,abstract,interface,package...

代码块

从格式上来讲就是一对大括号{}

  1. 作用:初始化类、对象
  2. 修饰:最多只能使用static来修饰,分为静态代码块和非静态代码块。

(下方代码都是在以下代码中讲解)

创建的是Person类,main方法中创建的是Person的对象。

class Person{
	String name;
	int age;
	static String desc = "我是一个人";
	
	public Person() {
		
	}

	public Person(String name, int age) {
		this.name = name;
		this.age = age;
	}
	
	//代码块
	static {
		System.out.println("hello,static block");
	}
	
	{
		System.out.println("hello,block");
	}
	
	
	public void eat() {
		System.out.println("吃饭");
	}

	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + "]";
	}
	
	public static void info() {
		System.out.println("我是一个快乐的人!");
	}
	
}

静态代码块

  • 内部可以有输出语句
  • 随着类的加载而执行,而且只能执行一次
  • 作用:初始化类的信息
  • 可以定义多个静态代码块,按照声明的顺序执行
  • 一定先执行静态代码块,再执行非静态代码块
  • 静态代码块只能调用静态的属性和方法,不能调用非静态的结构 比如上方代码中
static {
        System.out.println("hello,static block");
}

就是静态代码块,如果main方法按下方写,就会直接执行这个静态代码块。

String desc = Person.desc;

如果改成以下代码,就会初始化类的信息。

static {
        System.out.println("hello,static block");
        desc = "我是一个爱学习的人";
}

非静态代码块

  • 内部可以有输出语句
  • 随着对象的创建的调用而执行,而且每造一个对象都会执行一次
  • 作用:可以在创建对象时,可对对象的属性等进行初始化。
  • 非静态代码块内部可以调用静态的属性、静态的方法,或非静态的属性、非静态的方法。

比如上方代码中

{
        System.out.println("hello,block");
}

就是非静态代码块,如果main方法按下方写,就会直接执行两次这个非静态代码块。

Person p1 = new Person();
Person p2 = new Person();

可以对属性进行赋值

{
        System.out.println("hello,block");
        age = 1;
}

属性可以赋值的位置:

  1. 默认初始化
  2. 显式初始化
  3. 构造器初始化
  4. 有了对象之后,可以通过“对象.属性”或“对象.方法”的方式,进行赋值
  5. 在代码块中赋值

先后顺序:1->2/5->3->4


内部类

Java中允许将一个类A声明在另一个类B中,则类A就是内部类,类B就是外部类。

内部类的分类

class Person{
	String name;
	int age;
	
	public void eat() {
		System.out.println("人:吃饭");
	}
	//静态成员内部类
	static class Dog{
		String name;
		int age;
		public void show() {
			System.out.println("卡拉是条狗");
		}
	}
	//非静态成员内部类
	class Bird{
		String name;
		public Bird() {
			
		}
		
		public void sing() {
			System.out.println("我是一只鸟");
		}
                
                public void display(String name) {

		}
	}
	
	
	public void method() {
		//局部内部类
		class AA{
			
		}
	}
	
	{
		class BB{
			
		}
	}
	
	public Person() {
		class CC{
			
		}
	}
}

✨成员内部类(静态与非静态)

一方面:作为外部类的成员

  • 调用外部类的结构
  • 可以被static修饰
  • 被四种不同权限修饰符修饰

另一方面,作为一个类:

  • 类内可以定义属性、方法、构造器等
  • 可以被final修饰,表示此类不能被继承。言外之意,不使用final,就可以被继承。
  • 可以被abstract修饰,表示不能被实例化

✨局部内部类(方法内,代码块内,构造器内)


有关内部类的三个问题

  1. 如何实例化成员内部类的对象 以上面的Person类为例,如果想创建Dog类的对象(即静态的成员内部类)
public static void main(String[] args) {
        Person.Dog dog = new Person.Dog();
}

创建Bird实例(非静态的成员内部类)

public static void main(String[] args) {
        Person p = new Person();
        Person.Bird bird = p.new Bird();
        bird.sing();
}
  1. 如何在成员内部类中区分调用外部类的结构 在上面的Person类中我们发现Person类里有一个name,Bird类里也有一个name,Bird类有一个方法的形参也有一个name,下面就是区分三个name的方法。
public void display(String name) {
        System.out.println(name);//方法的形参
        System.out.println(this.name);//Bird内部类的name
        System.out.println(Person.this.name);//Person外部类的name
}
  1. 开发中局部内部类的使用
public class InnerClassTest1 {
	//开发中很少见
	public void method() {
		//局部内部类
		class AA{
			
		}
	}
	//返回一个实现了Comparable接口的类的对象
	public Comparable getComparable() {
		//创建一个实现了Comparable接口的类:局部内部类
		class MyComparable implements Comparable{

			@Override
			public int compareTo(Object o) {
				// TODO Auto-generated method stub
				return 0;
			}
			
		}
		return new MyComparable();
	}
}