在学习内部类之前,我们先了解一下,类的五大成员是哪些?
内部类就是在一个类或方法中定义的类。内部类又分为成员内部类,静态内部类,匿名内部类和局部内部类。
成员内部类是定义在类的内部,作为类的成员的类。
public class Outer {
private Inner inner=null;
private double r;
String b;
public Inner getInnerInstance(){//用于返回一个内部类对象
if (inner==null)
inner=new Inner();
return inner;
}
private class Inner{//成员内部类,用private修饰,只能外部类的内部访问
final static int t=1;//成员内部类不能定义静态成员,final修饰的除外
public void draw(){
System.out.println("绘制一个圆,半径为"+r);
}
}
}
特点如下:
//第一种方式
Outer outer=new Outer();
Outer.Inner inner=outer.new Inner();
//第二种方式
Outer.Inner inner1=outer.getInnerInstance();//在外部类提供一个方法,返回一个内部类对象
外部类.this.成员变量/成员方法
使用static修饰的成员内部类我们称之为静态内部类。
public class Test {
public static void main(String[] args) {
Outer.Inner inner=new Outer.Inner();//静态内部类可以被其他类直接访问和实例化,而不需要先实例化外部类。
inner.draw();
}
}
class Outer {
int t=0;
static String desc="123";
static class Inner{
static int x=10;
{
System.out.println("这里是静态内部类的代码块");
}
public static void draw(){
System.out.println("t的值:");//这里会编译报错
System.out.println("desc的值:"+desc);
}
}
}
特点如下:
匿名内部类没有显式的类名,通常在创建对象的时候定义,可以直接在表达式中使用,不需要单独声明一个命名的类。在jdk8新特性中可以使用Lambda表达式替代。
public class Test {
public static void main(String[] args) {
Calculator calculator=new Calculator() {// 创建一个匿名内部类实现Calculator接口
@Override
public int calculate(int a, int b) {
return a + b;
}
};
System.out.println(calculator.calculate(2,3));
}
}
interface Calculator {
int calculate(int a, int b);
}
匿名内部类可以出现在任何允许表达式出现的地方
,比如方法参数、变量初始化、方法返回值等。定义格式:
new 父类构造器(参数列表)或 实现接口()
{
//匿名内部类的类体部分
}
特点:
注:匿名内部类是唯一一种没有构造器的类。匿名内部类用于继承其他类或是实现接口,并不需要增加额外的方法,只是对继承方法的实现或是重写。
Lambda表达式并不能取代所有的匿名内部类,能够使用Lambda的依据是必须有相应的函数接口(函数接口,是指内部只有一个抽象方法的接口)。
如果需要新建一个线程,匿名内部类写法:
new Thread(new Runnable(){// 接口名
@Override
public void run(){// 方法名
System.out.println("Thread run()");
}
}).start();
Lambda表达式简化写法:
new Thread(
() -> { // 省略接口名和方法名
System.out.print("Hello");
System.out.println("Jack");
}
).start();
//如果函数体只有一行语句,花括号直接去掉,留下那一行语句,比如() -> System.out.println("Thread run()")
如果要给一个字符串列表通过自定义比较器,按照字符串长度进行排序,匿名内部类写法:
List<String> list = Arrays.asList("I", "love", "you");
Collections.sort(list, new Comparator<String>(){// 接口名
@Override
public int compare(String s1, String s2){// 方法名
if(s1 == null) return -1;
if(s2 == null) return 1;
return s1.length()-s2.length();
}
});
Lambda表达式简化写法:
List<String> list = Arrays.asList("I", "love", "you");
Collections.sort(list, (s1, s2) ->{// 省略参数表的类型
if(s1 == null) return -1;
if(s2 == null) return 1;
return s1.length()-s2.length(); });
自定义函数接口,只需要编写一个只有一个抽象方法的接口即可。
// 自定义函数接口
@FunctionalInterface //这个注解是可选的,但加上该标注编译器会帮你检查接口是否符合函数接口规范。
interface MyInterface<T>{
void doSomething(T t);
}
class Test<T>{
private List<T> list;
public void myForEach(MyInterface<T> myInterface){
for (T t:list) {
myInterface.doSomething(t);
}
}
public static void main(String[] args) {
Test test=new Test();
test.list= Arrays.asList(12,13,14,15,16,17);
test.myForEach(str->System.out.println(str));// 使用自定义函数接口书写Lambda表达式
}
}
*需要注意的是:*
lambda表达式隐含了return关键字,所以在单个的表达式中,我们无需显式的写return关键字,
但是当表达式是一个语句集合的时候,则需要显式添加return,并用花括号{ }将多个表达式包围起来,下面看几个例子:
//返回给定字符串的长度,隐含return语句
(String s) -> s.length()
// 始终返回42的无参方法
() -> 42
// 包含多行表达式,则用花括号括起来
(int x, int y) -> {
int z = x * y;
return x + z;
}
局部内部类是定义在一个方法或者一个作用域里面的类,它和成员内部类的区别在于局部内部类的访问仅限于方法内或者该作用域内。
作用域指的是方法里的代码块(如 if/else 语句块、for 循环块、while 循环块等)。
class Outer{
public void test(){
int x=20;
class Inner{ //在方法内定义
public void print(){
System.out.println("我今年"+x);
}
}
new Inner().print(); // 局部内部类必须在方法内部实例化,然后return出去或者直接调用其方法。
}
public static void main(String[] args) {
Outer outer = new Outer();
outer.test();
}
}
特点如下:
成员内部类实现多继承:
class Father {
public int eat(){
return 10;
}
}
class Mother {
public int fly(){
return 20;
}
}
class Son {
class Father_1 extends Father{
public int eat(){
return super.eat() + 10;
}
}
class Mother_1 extends Mother{
public int fly(){
return super.fly() - 7;
}
}
public int geteat(){
return new Father_1().eat();
}
public int getfly(){
return new Mother_1().fly();
}
}
public class Test {
public static void main(String[] args) {
Son son = new Son();
System.out.println( son.geteat());
System.out.println( son.getfly());
}
}
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- huatuo9.cn 版权所有 赣ICP备2023008801号-1
违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务