Java类与对象概述(二)
1. 代码块
- 普通代码块
- 构造块
- 静态块
- 同步代码块(与线程相关)
1.1 普通代码块
- 定义在方法中的代码块
- 代码中的变量,只在当前块中有效
- 一般代码较长,是为了防止变量名不重名,使用该块
public class Test{
public static void main(String[] args){
{
int x = 10;
System.out.println(x);
}
System.out.println(x); //编译错误,找不到符号x
}
}
1.2 构造块
- 定义在类中的代码块(不加修饰符)
- 构造块优先于构造方法执行,每new一个对象,执行一次构造块
class Person{
{
System.out.println("这是一个构造块");
}
public Person(){
System.out.println("这是一个构造方法");
}
}
public class Test{
public static void main(String[] args){
new Person(); //每new一个对象,执行构造块-->构造方法
System.out.println("--------");
new Person();
}
}
/*
这是一个构造块
这是一个构造方法
----------
这是一个构造块
这是一个构造方法
*/
1.3 静态代码块
- 使用static定义的代码块
- 分类:1.在主类;2.在非主类
1.3.1 在非主类的静态代码块
- 静态块先执行–> 构造块—>构造方法
- 每new实例化一个对象,静态块只执行一次
- 静态块作用:为static属性进行初始化
class Person{
static{
System.out.println("这是一个静态块");
}
{
System.out.println("这是一个构造块");
}
public Person(){
System.out.println("这是一个构造方法");
}
}
public class Test3{
public static void main(String[] args){
System.out.println("------start------");
new Person();
System.out.println("-----------------");
new Person();
System.out.println("------end--------");
}
}
/*
-------start--------
这是一个静态块
这是一个构造块
这是一个构造方法
--------------------
这是一个构造块
这是一个构造方法
-------end----------
*/
1.3.2 在主类的静态代码块
- 静态方法优先于main方法执行
public class Test{
static{
System.out.println("这是一个静态块");
}
{
System.out.println("这是一个构造块");
}
public Test(){
System.out.println("这是一个构造方法");
}
public static void main(String[] args){
System.out.println("-------start------");
new Test();
System.out.println("------------------");
new Test();
System.out.println("------end---------");
}
}
/*
这是一个静态块
------start------
这是一个构造块
这是一个构造方法
-----------------
这是一个构造块
这是一个构造方法
------end--------
*/
2. 内部类的定义与使用
- 定义:内部类就是在一个类的内部进行其他类得结构的嵌套操作
- 内部类的作用:
- 1.内部类方法可以访问该类定义所在作用域中的数据,包括被private修饰的私有数据
- 2.内部类可以对同一包中的其他类隐藏起来
- 3.内部类可以实现java单继承的缺陷
- 4.当我们想要定义一个回调函数,却不想写大量代码时候我们可以选择匿名内部类来实现
举例:使用内部类实现“多继承”
class A{
private String name = "A的私有域";
public String getName(){
return this.name;
}
}
class B{
private int age = 20;
public int getAge(){
return this.age;
}
}
class Outer{ //Outer利用内部类继承了两个类A与B
private class InnerClassA extends A{
public String name(){
return super.getName();
}
}
private class InnerClassB extends B{
public int age(){
return super.getAge();
}
}
public String name(){
return new InnerClassA().name();
}
public int age(){
return new InnerClassB().age();
}
}
public class Test{
public static void main(String[] args){
Outer out = new Outer();
System.out.println(out.name());
System.out.println(out.age());
}
}
/*
A的私有域
20
*/
2.1 内部类与外部类的关系
- 对于非静态内部类,内部类的创建依赖外部类的实例对象,在没有外部类实例之前是无法创建内部类的
- 内部类可以直接访问外部类的元素(包含私有域),但是外部类不能直接访问内部类元素
- 外部类可以通过内部类引用间接访问内部类元素
举例:内部类直接访问外部类元素
class Outer{
private String msg ="hello,world";
class Inner{
private String msg = "hello,xi'an";
public void print(){
System.out.println(Outer.this.msg); //如果写成this.msg/msg 访问的是本类属性
}
}
}
public class Test{
public static void main(String[] args){
Outer.Inner in = new Outer().new Inner(); //在外部类的外部实例化一个内部类
in.print();
}
}
// hello,world
在外部类外部创建内部类:外部类.内部类 内部对象 = new 外部类().new 内部类();
举例:外部类可以通过内部类引用(对象地址)间接访问内部类元素
class Outer{
private String msg ="hello,world";
class Inner{
private String msg = "hello,xi'an";
public void print(){
System.out.println(this.msg); //如果写成this.msg/msg 访问的是本类属性
}
}
public void fun(){
Innner in = new Inner(); //在外部类内部实例化内部类对象
in.print(); //内部类对象调用实例化方法
}
}
public class Test{
public static void main(String[] args){
Outer out = new Outer();
out.fun();
}
}
//hello,xi'an
在外部类内部创建内部类(普通对象一样创建):内部类 内部类对象 = new 内部类();
2.2 内部类分类
分类:
- 成员内部类
- 静态内部类
- 方法内部类
- 匿名内部类
2.2.1 成员内部类
1.成员内部类中不能存在任何static的变量和方法
2.成员内部类是依附于外围类的,所以只有先创建了外围类才能够创建内部类
2.2.2 静态内部类
- 定义:使用static修饰的内部类成为静态类
- static关键字可以修饰成员变量、方法、代码块
1.静态内部类的创建不需要依赖外围类,可以直接创建
2.静态内部类不可以使用任何外围类的非static成员变量和方法。而内部类都可以
外部类创建语法:外部类.内部类 内部类对象 = new 外部类.内部类();
举例:使用static创建静态内部类
class Outer{
private static String msg = "hello,world";
static class Inner{
public void print(){
System.out.println(Outer.msg);
}
}
}
public class Test{
public static void main(String[] args){
Outer.Inner in = new Outer.Inner();
in.print();
}
}
//hello,world
2.2.3 方法内部类
- 定义:方法(局部)内部类定义在外部类的方法中
- 方法内部类和成员内部类基本一致,只是作用域不同。方法内部类在方法内部被使用,出了该方法就会失效
1.方法内部类不允许使用访问权限修饰符public,private,protected
2.局部内部类对外完全隐藏,除了创建这个类的方法可以访问,其他地方不允许访问
3.局部内部类想要使用方法形参,该形参必须用final声明(JDK8形参变为隐式final声明)
举例:使用方法内部类
class Outer{
private int num = 3;
public int getNum(){
return this.num;
}
public void display(int test){
class Inner{
private void fun(){
num++;
System.out.println(num);
System.out.println(test);
}
}
new Inner().fun();
}
}
public class Test{
public static void main(String[] args){
Outer out = new Outer();
out.display();
System.out.println(out.getNum);
}
}
/*
4
20
4
*/
2.2.4 匿名内部类
- 定义:匿名内部类就是一个没有名字的方法内部类
1.匿名内部类没有访问修饰符
2.匿名内部类必须继承一个抽象类或者接口
3.匿名内部类中不能存在任何静态成员和方法
4.匿名内部类没有构造方法,因为它没有类名
5.与局部内部类相同,匿名内部类也可以引用方法形参,形参必须声明为final
举例:使用匿名内部类
interface MyInterface{
void test();
}
class Outer{
private int num;
public void display(int test){
new MyInterface(){
@override
public void test(){
System.out.println(test);
}
}.test();
}
}
public class Test{
public static void main(String[] args){
Outer out = new Outer();
out.display(20);
}
}
//20