内部类是指在外部类内定义的类分类:有名内部类: 引用方式:
package com.lei;
public class Outclazz {
class Innerclass{
void print(){
System.out.println("内部类");
}
}
}
package com.lei;
import com.lei.Outclazz.Innerclass;//必须引用该内部类才能将内部类的范围拓展到这儿
public class Test {
public static void main(String[] args) {
Outclazz outclazz = new Outclazz();
// Innerclass innerclass = outclazz.new Innerclass();//先创建一个外部类对象再引用该内部类与成员变量相似
// innerclass.print();
outclazz.new Innerclass().print();
}
}
匿名内部类:引用方式 匿名内部类由于没有类名而不能单独存在,定义匿名内部类的同时须直接实例化该类,其语法格式如下: new 父类构造器([参数列表])|接口(){ //匿名内部类类体 } 抽象类:抽象类的匿名内部类实质为抽象类的子类
package com.lei;
public abstract class Outclassone {
public abstract void works();
public static void main(String[] args) {
new Outclassone() {
@Override
public void works() {
// TODO Auto-generated method stub
}
}.works();//可直接调用
}
}
普通类:普通类匿名内部类实质为普通类的子类
package com.lei;
class Mammal {
public void move() {
System.out.println("正在移动......");
}
}
public class Sea {
public static void main(String[] args) {
Mammal whale = new Mammal() {//调用Mammal中的无参构造方法还有上转型对象
@Override
public void move() {
System.out.println("鲸鱼靠鳍移动......");
}
};
whale.move();
}
}
接口:接口的匿名内部类实质为接口的实现类
package com.lei;
interface IOut {
public abstract void work();
public default void works() {
System.out.println("deaults");
}
}
public class Testtwo{
public static void main(String[] args) {
IOut uts = new IOut() {
@Override
public void work() {
System.out.println("重写后的方法");
}
};
uts.work();
uts.works();
}
匿名内部类一定是接口的实现类(该实现类仅能实现一个接口)或类(普通类或抽象类)的子类,其中new 关键字后面的类名或接口名即是该匿名内部类继承的父类或实现的接口; 匿名内部类不能自定义构造方法,但是可以通过非静态代码块初始化成员变量; 匿名内部类一定不能是抽象类; 可以在匿名内部类中添加新的属性和方法,但是这些属性和方法不能被上转型对象所调用,只能被非上转型对象方式创建的匿名内部类对象所调用, 静态内部类:按照是否有static修饰分为静态内部类和非静态内部类,有static修饰的为静态内部类,没有static修饰的为非静态内部类。 静态匿名内部类:
package com.lei;
class Father {
public void eat() {
System.out.println("筷子吃饭....");
}
}
/**
* 外部类
*/
public class Tests {
/**
* 匿名内部类
*/
static Father Son = new Father(){
@Override
public void eat() {
System.out.println("筷子吃饭....");
}
};
public static void main(String[] args) {
Son.eat();
}
}
但是static内部类只能定义在外部类中。 静态内部类仅能直接访问外部类的静态成员变量和方法,可以通过创建外部类的对象间接使用非静态的成员变量和方法。
public class OutClass {
private double weight=72;
public static void print(String name) {
System.out.println(name);
}
static class InClass{
{
double weight = new OutClass().weight;//由于weight是非静态的,所以在静态内部类中使用时必须先创建外部类对象
print("Tom");//由于print方法为静态方法,所以可以直接使用。
}
}
}
在非外部类中定义的内部类和局部变量一样,其使用范围从定义的位置开始到其所在直接语句块结束。 注意: 只有有名静态内部类中才允许有静态成员(静态属性、静态代码块和静态方法)。 内部类是一个独立的类:编译之后内部类会被编译成独立的.class文件,如果该内部类为有名内部类,则有名内部类字节码文件名为外部类的类名+$+内部类类名;如果为匿名内部类,则匿名内部类字节码文件名为外部类类名+$+数字; 普通外部类、抽象类和接口可以有内部类(匿名的或有名的); 内部类可以直接定义在类中,也可以定义在方法或代码块中;其中直接定义在外部类中的内部类可以有public、protected、默认的和private四种访问权限修饰(普通外部类、接口和抽象类只能使用public和default修饰),也可以使用static修饰( static不能修饰普通外部类、接口和抽象类);但是定义在方法或代码块中的内部类不能有访问修饰符修饰,也不能有static修饰。 Lambda 表达式 如果方法有返回值且只有一行代码,则Lambda表达式语法可以是这种形式:([参数1], [参数2], [参数3],.... [参数n])->表达式; Java支持Lambda 表达式始于Java 8,它的出现简化了函数式接口匿名内部类的语法,其表达式语法如下:([参数1], [参数2], [参数3],.... [参数n])->{代码块}
@FunctionalInterface
interface IComputer {
int add(int a, int b);
}
public class Test {
public static void main(String[] args) {
IComputer computer = (a, b) -> a+b;
int result = computer.add(1,2);
System.out.println(result);
}
}
|