java:内部类,
java:内部类,
文章目录
- 一.内部类分类
- ①有名内部类
- ②匿名内部类
- 匿名内部类特点
- ③.静态内部类
- 二.内部类特点
- 三.Lambda表达式特点
一.内部类分类
内部类是指在一个外部类内定义的类
按照是否有类名分为有名内部类和匿名内部类
①有名内部类
说明:全局有名内部类的使用方式类似于全局变量;局部有名内部类的使用方式类似局部变量——它们都有固定的使用范围
例子
package com.neibuwaibu;
public class Body {
class Heart{
public void beat() {
System.out.println("正在跳动");
}
}
public void print(){
int a=0;
if(a==0) {
class Heart{
public void beat() {
System.out.println("正在跳动");
}
}
Heart heart=new Heart();
heart.beat();
}
}
public static void main(String[] args) {
}
}
package com.neibuwaibu;
import com.neibuwaibu.Body.Heart;
public class Test {
public static void main(String[] args) {
Body body=new Body();
Heart heart=body.new Heart();
heart.beat();
}
}
②匿名内部类
匿名内部类由于没有类名而不能单独存在,定义匿名内部类的同时须直接实例化该类,其语法格式如下:
new 父类构造器([参数列表])|接口(){
//匿名内部类类体
}
① 普通类:普通类匿名内部类实质为普通类的子类
②抽象类:抽象类匿名内部类实质为抽象类的子类
③接口:接口匿名内部类实质为接口的实现类
匿名内部类特点
- 匿名内部类一定是接口的实现类(该实现类仅能实现一个接口)或类(普通类或抽象类)的子类,其中new
- 关键字后面的类名或接口名即是该匿名内部类继承的父类或实现的接口; 匿名内部类不能自定义构造方法,但是可以通过非静态代码块初始化成员变量;
- 匿名内部类一定不能是抽象类
- 可以在匿名内部类中添加新的属性和方法,但是这些属性和方法不能被上转型对象所调用,只能被非上转型对象方式创建的匿名内部类对象所调用
例子:
package com.neibuwaibu;
//① 普通类
// class Mammal {
//
// public void move() {
// System.out.println("正在移动......");
// }
// }
//
// public class Sea {
//
// Mammal whale = new Mammal() {//调用Mammal中的无参构造方法
//
// @Override
// public void move() {
// System.out.println("鲸鱼靠鳍移动......");
// }
// };
// public static void main(String[] args) {
// Sea sea=new Sea();
// sea.whale.move();
// }
//}
// ②抽象类
//abstract class Mammal {
//
// public Mammal(String name) {
// System.out.println(name);
// }
//
// abstract void move();
//}
//
//public class Sea {
//
// Mammal mammal = new Mammal("鲸鱼") {// 调用Mammal中的有参构造方法
//
// @Override
// void move() {
// System.out.println("鲸鱼靠鳍移动......");
// }
// };
// public static void main(String[] args) {
// Sea sea=new Sea();
// sea.mammal.move();
// }
//}
//③接口
interface Mammal {
abstract void move();
}
//public class Sea {
//
// Mammal mammal = new Mammal() {
//
//
// int age=2;
// {
// age=10;
// }
// public void print() {
// System.out.println("lll");
// }
// @Override
// public void move() {
// System.out.println("鲸鱼靠鳍移动......");
// }
// };
public class Sea {
public static void main(String[] args) {
new Mammal() {
int age=2;
{
age=10;
}
public void print() {
System.out.println("lll");
}
@Override
public void move() {
System.out.println("鲸鱼靠鳍移动......");
}
}.print();
// Sea sea=new Sea();
// sea.mammal.move();
}
③.静态内部类
按照是否有static修饰分为静态内部类和非静态内部类,有static修饰的为静态内部类,没有static修饰的为非静态内部类
静态有名内部类
Body:
package com.neibuwaibu;
public class Body {
static class Heart{
public void beat() {
System.out.println("正在跳动");
}
}
}
Test:
package com.neibuwaibu;
import com.neibuwaibu.Body.Heart;
public class Test {
public static void main(String[] args) {
Heart heart = new Body.Heart();
heart.beat();
}
}
静态匿名内部类
package com.neibuwaibu;
interface Mammal {
abstract void move();
}
public class Sea {
static Mammal mammal = new Mammal() {
int age=2;
{
age=10;
}
public void print() {
System.out.println("lll");
}
@Override
public void move() {
System.out.println("鲸鱼靠鳍移动......");
}
};
}
1.如果为static内部类只能直接定义在外部类中
2.静态内部类仅能直接访问外部类的静态成员变量和方法,可以通过创建外部类的对象间接使用非静态的成员变量和方法
3.在非外部类中定义的内部类和局部变量一样,其使用范围从定义的位置开始到其所在直接语句块结束
4.只有有名静态内部类中才允许有静态成员(静态属性、静态代码块和静态方法)
二.内部类特点
内部类是一个独立的类:编译之后内部类会被编译成独立的.class文件,如果该内部类为有名内部类,则有名内部类字节码文件名为外部类的类名++数字;
例子:
①普通外部类、抽象类和接口可以有内部类(匿名的或有名的)
②内部类可以直接定义在类中,也可以定义在方法或代码块中
③直接定义在外部类中的内部类可以有public、protected、默认的和private四种访问权限修饰(普通外部类、接口和抽象类只能使用public和default修饰),也可以使用static修饰( static不能修饰普通外部类、接口和抽象类)
④但是定义在方法或代码块中的内部类不能有访问修饰符修饰,也不能有static修饰。
⑤内部类可以访问外部类的所有访问权限的成员变量
例子:
package com.neibuwaibu;
interface Imammal{
}
public class Sea{
private int age;
private class InClass{
{
System.out.println();
}
}
public static void main(String[] args) {
// class InClass{
// {
// System.out.println();
// }
// }
}
}
三.Lambda表达式特点
Lambda表达式特点简化了函数式接口匿名内部类的语法,java从Java8开始支持使用Lambda表达式
其表达式语法如下:([参数1], [参数2], [参数3],… [参数n])->{代码块}
从匿名内部类转到Lambda表达式
接口:
interface IMammal {
void move(String name);
}
匿名内部类:
public class Test {
public static void main(String[] args) {
Mammal mammal = new Mammal() {
@Override
public void move(String name) {
System.out.println("鲸鱼靠鳍移动......");
}
};
whale.move("小白");
}
}
Lambda 表达式:
import java.util.Date;
public class Test {
public static void main(String[] args) {
Mammal mammal = (name) ->System.out.println("鲸鱼靠鳍移动......");
whale.move("小白");
}
}
①如果方法没有返回值且只有一行代码,则Lambda表达式语法可以是这种形式:([参数1], [参数2], [参数3],… [参数n])->单行语句
②如果方法有返回值且只有一行代码,则Lambda表达式语法可以是这种形式:([参数1], [参数2], [参数3],… [参数n])->表达式
相关文章
- 暂无相关文章
用户点评