内部类

内部类

1.什么是内部类

内部类是指在一个外部类内定义的类。

2.内部类的分类

内部类可分为有名内部类和匿名内部类。其中,有名内部类按照是否有static修饰分为静态内部类和非静态内部类。
在这里插入图片描述

3.内部类的位置

package human;

public class Body {
	int age;
	String sex;
	/*
	 * 直接定义在外部类中的内部类
	 */
	class Heart {   	
		void beat() {
			System.out.println("心脏跳动");
		}
	}
	/*
	 * 定义在代码块中的内部类
	 */
	{
		class Leg{  //静态内部类
			void walking() {
				System.out.println("腿迈动");
			}
		}
		Leg leg = new Leg();
		leg.walking();
	}
	/*
	 * 定义在方法中的内部类
	 */
	public void Look(){
		class Eye{
			public void see() {
				System.out.println("眼睛在看");
			}
		}
		Eye eye = new Eye();
		eye.see();
	}
}


Test类:

package human;

import human.Body.Heart;

public class Test {
	public static void main(String[] args) {
		Body body = new Body();
		Heart heart = body.new Heart();
		heart.beat();
		body.Look();
	}
}

Test类运行结果
在这里插入图片描述

其中,直接定义在外部类中的内部类可以由public、protected、默认的和private四种访问权限修饰(普通外部类、接口和抽象类只能使用public和default修饰),也可以使用static修饰( static不能修饰普通外部类、接口和抽象类);
但是定义在方法或代码块中的内部类不能有访问修饰符修饰,也不能有static修饰。
注意:
在非外部类中定义的内部类和局部变量一样,其使用范围从定义的位置开始到其所在直接语句块结束。

public class OutClass {
	public static void main(String[] args) {
		if(args!=null) {
			class InClass{
				
			}
		}
		InClass inClass = new InClass();//无法创建对象,因为内部类作用范围无法作用到这里
	}
}

4.有名内部类

1.静态内部类

定义:有名内部类中,没有static修饰的为非静态内部类。

  • 静态内部类只能直接定义在外部类中
    如下代码将会提示错误:
public class OutClass {

	public static void main(String[] args) {
		/**
		 * 静态有名内部类
		 */
		static class InClass {

			public void printInfo() {
				System.out.println("我是有名内部类");
			}
		}
	}
}

在这里插入图片描述
提示表明该类的位置非法

  • 静态内部类仅能直接访问外部类的静态成员变量和方法,可以通过创建外部类的对象间接使用非静态的成员变量和方法。

在这里插入图片描述

  • 只有有名静态内部类中才允许有静态成员(静态属性、静态代码块和静态方法)。
    在这里插入图片描述

2.非静态内部类

非静态内部类可以调用静态和非静态成员变量,可以调用静态和非静态方法
在这里插入图片描述

5.匿名内部类

定义:匿名内部类就是一个没有显式的名字的内部类。

  • 匿名内部类由于没有类名而不能单独存在,定义匿名内部类的=同时须直接实例化该类,其语法格式如下:

    new 父类构造器 ( [参数列表 ] ) | 接口 ( ) {
            //匿名内部类类体
    }

1. 接口匿名内部类

创建接口类:IMammal0:

public interface IMammal0 {
	void move();
}

创建Ocean类,用于测试

public class Ocean {
	public static void main(String[] args) {
		IMammal0 mammal0 = new IMammal0() {//接口匿名内部类,是接口的实现类
		@Override
		public void move() {
			System.out.println("接口实现类的游泳");
			}
		};
		mammal0.move();
	}
}

运行,控制台输出:
在这里插入图片描述

2.抽象类匿名内部类

创建抽象类:IMammal1:

public abstract class Mammal1 {
	abstract void move();
}

测试类Ocean类:

public class Ocean {
	public static void main(String[] args) {
		Mammal1 mammal1 = new Mammal1() {  //抽象类的子类
		@Override
		void move() {
			System.out.println("抽象类的子类游动");
			}
		}; 
		mammal1.move();
	}
}

运行,控制台输出:
在这里插入图片描述

3.普通类的子类

创建I普通类IMammal2:

public class Mammal2 {
	void move() {
	}
}

测试类Ocean类:

public class Ocean {
	public static void main(String[] args) {
		Mammal2 mammal2 = new Mammal2() {//普通类的子类
		@Override
		void move() {
			System.out.println("普通类的子类游动");
			}
		};
		mammal2.move();
	}
}

运行,控制台输出:
在这里插入图片描述

4.特点
  • 匿名内部类一定是接口的实现类(该实现类仅能实现一个接口)或类(普通类或抽象类)的子类,其中new 关键字后面的类名或接口名即是该匿名内部类继承的父类或实现的接口;(上述第3点)
  • 匿名内部类没有名字,构造方法要求方法名和类名相同,所以匿名内部类不能自定义构造方法,但是可以通过非静态代码块初始化成员变量;
public class Test {
	class car{
		int age;
		{
			age = 10;
		}
	}
}
  • 匿名内部类一定不能是抽象类

    抽象类是只声明方法的存在而不去具体实现它的类。抽象类不能被实例化,也就是不能创建其对象。而匿名内部类在定义时直接实例化该类。

  • 可以在匿名内部类中添加新的属性和方法,但是这些属性和方法不能被上转型对象所调用(上转型对象不能调用新增属性和方法),只能被非上转型对象方式创建的匿名内部类对象所调用,例如:

public class Test {

	public static void main(String[] args) {

		IMammal whale = new IMammal() {
			public void breath() {
				System.out.println("鲸鱼正在呼吸......");
			}

			@Override
			public void move() {
				System.out.println("鲸鱼靠鳍游动......");
			}
		};//此时匿名内部类对象为上转型对象
		whale.breath();// 同一个匿名内部类对象只能调用一个新增的属性或方法,无法再调用抽象方法breath()、重写的方法或继承的方法,也无法调用继承的属性
上转型对象无法调用新增的breath方法
	}
}

interface IMammal {
	void move();
}

代码2:
public class Test {

	public static void main(String[] args) {

		new IMammal() {
			public void breath() {
				System.out.println("鲸鱼正在呼吸......");
			}

			@Override
			public void move() {
				System.out.println("鲸鱼靠鳍游动......");
			}
		}.breath();// 调用新增的breath方法
	}
}

interface IMammal {
	void move();
}

6.Lambda表达式

  • Java支持Lambda 表达式始于Java 8,它的出现简化了函数式接口匿名内部类的语法,其表达式语法如下:
         ([参数1], [参数2], [参数3],… [参数n])->{代码块}

先定义一个函数式接口:

package lambda;
@FunctionalInterface
public interface Calculate {
	void add(int a,int b);
}
  • 使用一般的内部类形式:
package lambda;

public class Computer {
	public static void main(String[] args) {
		Calculate calculate = new Calculate() {
		public void add(int a, int b) {
			System.out.println("结果是:"+(a+b));
		}
	};
	calculate.add(2, 3);
	}
}

运行,控制台输出为:在这里插入图片描述

  • 使用Lambda表达式:
package lambda;

public class Computer {
	public static void main(String[] args) {
		Calculate calculate = (int a, int b) -> {
			System.out.println("结果是:"+(a+b));
		};
		calculate.add(3, 3);
	}
}

运行,控制台输出
在这里插入图片描述

  • 另一种lambda表达式,省去变量类型声明:
package lambda;

public class Computer {
	public static void main(String[] args) {
		Calculate calculate = (a, b) -> {
			System.out.println("结果是:"+(a+b));
		};
	calculate.add(1, 3);
	}
}

运行,控制台输出
在这里插入图片描述

  • 如果方法没有返回值且只有一行代码,则Lambda表达式语法可以是这种形式:([参数1], [参数2], [参数3],… [参数n])->单行语句
package lambda;

public class Computer {
	public static void main(String[] args) {
		Calculate calculate = (a, b)->System.out.println("结果是:"+(a+b));
		calculate.add(1, 7);
	}
}

运行,控制台输出:
在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
内部类是指在一个类的内部定义的另一个类。内部类可以访问外部类的私有成员,而不需要使用访问器或者公共方法。 Java中有四种类型的内部类:成员内部类、局部内部类、匿名内部类静态内部类。下面分别介绍它们的写法。 1. 成员内部类 成员内部类是定义在外部类的成员位置上的类,它可以访问外部类的所有成员,包括私有成员。 ```java public class OuterClass { private int outerField; public class InnerClass { private int innerField; public void setOuterField(int value) { outerField = value; } public void setInnerField(int value) { innerField = value; } } } ``` 2. 局部内部类 局部内部类是定义在方法或码块内部的类,它只能在定义它的方法或码块中使用。 ```java public class OuterClass { private int outerField; public void method() { int localVariable = 0; class InnerClass { private int innerField; public void setOuterField(int value) { outerField = value; } public void setInnerField(int value) { innerField = value; } public void setLocalVariable(int value) { localVariable = value; // 局部变量必须是 final 或 effectively final } } InnerClass inner = new InnerClass(); inner.setOuterField(1); inner.setInnerField(2); inner.setLocalVariable(3); } } ``` 3. 匿名内部类 匿名内部类是没有名字的内部类,它通常用来实现接口或继承某个类。 ```java public class OuterClass { public void method() { Runnable runnable = new Runnable() { @Override public void run() { System.out.println("Hello, world!"); } }; Thread thread = new Thread(runnable); thread.start(); } } ``` 4. 静态内部类 静态内部类是定义在外部类内部的 static 类,它只能访问外部类的静态成员。 ```java public class OuterClass { private static int outerStaticField; public static class InnerClass { private int innerField; public void setOuterStaticField(int value) { outerStaticField = value; } public void setInnerField(int value) { innerField = value; } } } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值