面向对象之内部类
0.内部类
类中定义类
分类:
成员内部类
私有内部类
静态内部类
局部内部类
匿名内部类
Lambda表达式
1.成员内部类 :
内部类定义在外部类的成员位置
特点 :
即是成员,又是类,可以被成员修饰符所修饰,可以继承父类实现接口
在成员内部类中可以定义成员内容,也可以定义静态内容(不推荐),在jdk11及之前版本中除了静态内部类以外,其他内部类都不能定义静态内容,除了静态的常量
在成员内部类中,可以直接使用所在外部类的成员|静态的,包括私有的
在所在的外部类中可以通过对象使用成员内部类的成员,通过类名使用成员内部类中静态内容,包括私有的
在其他类中使用成员内部类中的静态内容,可以通过外部类类名.成员内部类类名.静态内容
在其他类中使用成员内部类中的成员内容,需要依赖所在外部类对象创建成员内部类对象,根据成员内部的对象调用成员
2.私有内部类 :
被private所修饰的成员内部类
特点 :
私有内部类中可以定义静态|非静态的成员
私有内部类中可以直接使用所在外部类的成员,包括私有的,包括静态的
在所在外部类中可以通过私有内部类的对象访问其成员,通过私有内部类的类名访问其静态内容,都包括私有的
私有的成员内部类在其他类中无法使用
3.静态内部类:
static修饰成员内部类
特点:
静态内部类中定义成员内容|静态内容
在静态内部类的方法中,可以直接使用所在外部类的静态内容,需要通过外部类对象访问外部类的成员内容,包括私有
在所在外部类中,可以直接通过静态内部类的类名调用其静态内容,可以通过静态内部的对象访问其成员内容
在其他类中,可以通过外部类类名.静态内部类类名.静态内容使用静态内部类的静态内容
在其他类中,可以通过new 外部类类名.静态内部类类名()对象访问静态内部类中的成员内容
4. 局部内部类 :
将内部类定义在局部位置
特点:
在局部内部类中可以定义静态(不推荐)|非静态成员
在局部内部类中可以直接使用所在外部类的成员,可以使用所在方法的局部变量
一旦在局部内部类中使用所在方法的局部变量,这个变量变为常量
jdk8之前版本 : 需要手动通过final修饰,将变量变为常量
jdk8开始 : 如果一旦在局部内部类中使用所在方法局部变量,会默认变为常量
在所在方法中可以通过类名.调用局部内部类中 的静态内容,通过局部内部类的对象访问其成员内容
局部内部类在外部类的其他方法中|其他类中都无法使用,只能在所在方法中使用
5.匿名内部类 :
省略了内部类的类名,将内部类的类体的定义与对象的创建合二为一,既能够实现对成员(类体)正确使用调用,也能够简化代码
new String().length()
特点:
分析
适合使用匿名内部类简化的类型
1)类没有自己本身的意义
2)实现类|子类只在当前使用一次
匿名对象 : 只能在当前行使用一次
语法 :
new 接口名|父类名 (){ //接口的实现类类体|抽象类的子类类体-->匿名内部类的类体 };
需求 : 调用接口中的一个抽象方法
1)定义实现类+重写抽象方法
2)创建实现类对象
Test t = new Test();
3)通过实现类对象调用重写方法
t.swimming();
1)+2)通过匿名内部类简化
匿名内部类使用方式
1: 匿名对象
new Swim(){
@Override
public void swimming() {
System.out.println("狗刨....");
}
}.swimming();
2 : 引用指向--->多态,可以多次使用这个匿名内部类对象
Car c = new Car(){
@Override
void run() {
System.out.println("一辆小汽车在跑...");
}
};
Swim s = new Swim(){
@Override
public void swimming() {
System.out.println("自由泳....");
}
};
c.run();
s.swimming();
3 : 将匿名内部类对象作为方法的实参
test(new Swim() {
@Override
public void swimming() {
System.out.println("仰泳....");
}
});
6.Lambda(拉曼达)表达式 :
java8新特性之一
作用 : 简化匿名内部类对象
前提 : 函数式接口
内部必须被重写的抽象方法只有一个的接口
强制检测是否为函数式接口 : @FunctionalInterface
语法 :
()->{}
() : 实现类中对接口中唯一的抽象方法的重写的参数列表
-> : 箭头函数 | 箭头符号 ,具有上下文推到作用
{} : 重写抽象方法的方法体
注意 : 当函数式接口作为引用类型|形参类型,赋值|传递实参可以为lambda表达式
匿名内部类 : 实现类的定义
Smoke s = new Smoke(){
@Override
public void smoking() {
System.out.println(".....");
}
};
Lambda表达式写法1 : 标准写法
Smoke s = () -> {
System.out.println(".....");
};
Lambda表达式写法2 : 当lambda体{}中语句 只有一句,前后的{}可以省略
Smoke s = () -> System.out.println(".....");
Lambda表达式写法3 : 当()中的存在参数的时候,参数的类型可以省略
Smoke s = (x, y) -> System.out.println("....."+(x+y));
Lambda表达式写法4 : 当()中的存在参数的时候,参数个数只有一个,前后的()可以省略
Smoke s = x -> System.out.println("....."+(x));
Lambda表达式写法5 : 当lambda体{}中语句只有一句,并且为return带出返回值语句,前后的{}与return关键字可以一起省略
Smoke s = x -> x>=18;
public class Class001_Outer {
public static void main(String[] args) {
System.out.println(Outer01.Inner.b);
Outer01.Inner.testStatic();
//外部类对象
Outer01 outer1 = new Outer01();
//创建成员内容类对象
//Outer01.Inner in = outer1.new Inner();
Outer01.Inner in = new Outer01().new Inner();
System.out.println(in.a);
}
}
class Outer01{
private int i = 1;
private static int j = 2;
//成员内部类
class Inner{
public int a = 5;
public static int b = 10; //不推荐静态内容
public void innerTest(){
System.out.println("内部类中的成员方法");
System.out.println(a);
System.out.println(b);
System.out.println(i);
System.out.println(j);
}
public static void testStatic(){
System.out.println("静态方法");
}
}
public void outerTest(){
System.out.println("所在外部类的成员方法");
//测试使用成员内部类的内容
Inner in = new Inner();
System.out.println(in.a);
System.out.println(Inner.b);
System.out.println(in.b);
}
}
package com.yjxxt;
//区分同名变量问题
public class Class002_Test {
public static void main(String[] args) {
new Outer2().new Inner().inner();
}
}
class Outer2{
int i=1;
class Inner{
int i=2;
public void inner(){
int i=3;
//调用的是局部变量 inner方法中的变量i=3
System.out.println(i);
//调用的是内部类Inner作用的变量i=2
System.out.println(this.i);
//调用的外部类中的变量i
System.out.println(Outer2.this.i);
}
}
}
public class Class003_Outer {
public static void main(String[] args) {
}
}
class Outer03{
private int i = 1;
private static int j = 2;
//私有内部类
private class Inner{
private int a = 5;
private static int b = 10; //不推荐
public void innerTest(){
System.out.println("私有内部类中的成员方法");
System.out.println(i);
System.out.println(j);
}
}
public void outerTest(){
System.out.println("所在外部类的成员方法");
System.out.println(Inner.b);
Inner in = new Inner();
System.out.println(in.a);
}
}
public class Class004_Outer {
public static void main(String[] args) {
//静态内不类中的静态内容
Outer04.Inner.testStatic();
//静态内不类中的成员内容
Outer04.Inner in = new Outer04.Inner();
in.testInner();
}
}
class Outer04{
private int i = 1;
private static int j = 2;
//静态内部类
static class Inner{
private int a = 5;
private static int b = 10;
public void testInner(){
System.out.println("静态内部类中的成员内容");
System.out.println(a);
System.out.println(b);
System.out.println(j);
System.out.println(new Outer04().i);
}
public static void testStatic(){
System.out.println("静态内部类中的静态内容");
System.out.println(b);
System.out.println(new Inner().a);
System.out.println(j);
System.out.println(new Outer04().i);
}
}
public void outerTest(){
System.out.println("所在外部类的成员方法");
Inner.testStatic();
System.out.println(Inner.b);
new Inner().testInner();
}
}
public class Class005_Outer {
public static void main(String[] args) {
}
}
class Outer05{
private int i = 1;
private static int j = 2;
public void outerTest(int args){
System.out.println("所在外部类的成员方法");
//局部
int m = 1;
//m = 100;
//局部内部类
class Inner{
private int a = 10;
private static int b = 20;//不推荐
public void testInner(){
System.out.println("局部内部类中的成员方法");
System.out.println(m);
System.out.println(i);
System.out.println(j);
}
}
//所在方法中测试使用局部内部类
System.out.println(Inner.b);
Inner in = new Inner();
System.out.println(in.a);
}
public void outer(){
System.out.println("外部类的成员方法");
}
}
public class Class006_Outer {
public static void main(String[] args) {
//匿名对象 : 只能在当前行使用一次
System.out.println(new String().length());;
System.out.println(new String().length());;
//需求 : 调用接口中的一个抽象方法
//1)定义实现类+重写抽象方法
//2)创建实现类对象
Test t = new Test();
//3)通过实现类对象调用重写方法
t.swimming();
t.swimming();
t.swimming();
//1)+2)通过匿名内部类简化
//1.匿名内部类使用方式1 : 匿名对象
new Swim(){
@Override
public void swimming() {
System.out.println("狗刨....");
}
}.swimming();
//2.匿名内部类使用方式2 : 引用指向--->多态,可以多次使用这个匿名内部类对象
Car c = new Car(){
@Override
void run() {
System.out.println("一辆小汽车在跑...");
}
};
Swim s = new Swim(){
@Override
public void swimming() {
System.out.println("自由泳....");
}
};
c.run();
c.run();
c.run();
c.run();
s.swimming();
s.swimming();
s.swimming();
s.swimming();
//3.匿名内部类的使用方式3 : 将匿名内部类对象作为方法的实参
test(new Swim() {
@Override
public void swimming() {
System.out.println("仰泳....");
}
});
}
//俱乐部
public static void test(Swim s){ //如果方法的形参为接口类型,方法的实参为接口的实现类对象
s.swimming();
}
}
abstract class Car{
abstract void run();
}
interface Swim{
void swimming();
}
//1)定义实现类
class Test implements Swim{
@Override
public void swimming() {
System.out.println("一边游泳一边喝水...");
}
}
public class Class007_Lambda {
public static void main(String[] args) {
//匿名内部类 : 实现类的定义
/*Smoke s = new Smoke(){
@Override
public void smoking() {
System.out.println(".....");
}
};*/
//Lambda表达式写法1 : 标准写法
/*Smoke s = () -> {
System.out.println(".....");
};*/
//Lambda表达式写法2 : 当lambda体{}中语句 只有一句,前后的{}可以省略
//Smoke s = () -> System.out.println(".....");
//Lambda表达式写法3 : 当()中的存在参数的时候,参数的类型可以省略
//Smoke s = (x, y) -> System.out.println("....."+(x+y));
//Lambda表达式写法4 : 当()中的存在参数的时候,参数个数只有一个,前后的()可以省略
//Smoke s = x -> System.out.println("....."+(x));
//Lambda表达式写法5 : 当lambda体{}中语句只有一句,并且为return带出返回值语句,前后的{}与return关键字可以一起省略
Smoke s = x -> x>=18;
System.out.println(s.smoking(18));
}
}
@FunctionalInterface
interface Smoke{
boolean smoking(int age);
}
本文详细介绍了Java中的内部类,包括成员内部类、私有内部类、静态内部类、局部内部类和匿名内部类的特点和用法。还涉及到了Lambda表达式的应用,作为简化匿名内部类的一种Java8新特性。
823





