内部类
概念
内部类的概念:将一个类定义在另一个类中
内部类的分类
-
按定义的位置来分
- 成员内部内,类定义在了成员位置 (类中方法外称为成员位置,无static修饰的内部类)
- 静态内部类,类定义在了成员位置 (类中方法外称为成员位置,有static修饰的内部类)
- 局部内部类,类定义在方法内
- 匿名内部类,没有名字的内部类,可以在方法中,也可以在类中方法外。
成员内部类的细节
编写成员内部类的注意点:
- 成员内部类可以被一些修饰符所修饰,比如: private,默认,protected,public,static等
- 在成员内部类里面,JDK16之前不能定义静态变量,JDK16开始才可以定义静态变量。
- 创建内部类对象时,对象中有一个隐含的Outer.this记录外部类对象的地址值。
例子
class B{
//成员内部类
// class A{
//
//
// }
public void fun1(){
//局部内部类
class A{
}
}
}
class Demo1{
int a = 10; // 成员变量
public void fun1(){
int b = 20; // 局部变量
}
}
public class InnerClassDemo1 {
public static void main(String[] args) {
}
}
成员内部类可以使用外部内中的任意权限修饰符修饰的成员变量
例子
/**
* 使用static关键字修饰成员内部类
*/
class Outer1{
static int a = 10;
private static int b = 20;
//成员内部类
static class Inner1{
int c = 20;
public void show1(){
System.out.println(a); // 成员内部类可以使用外部内中的任意权限修饰符修饰的成员变量
System.out.println(b);
c = 100;
System.out.println(c);
}
}
}
//class Outer1{
// int a = 10;
// private int b = 20;
//
// //成员内部类
// private class Inner1{
// int c = 20;
// public void show1(){
// System.out.println(a); // 成员内部类可以使用外部内中的任意权限修饰符修饰的成员变量
// System.out.println(b);
// c = 100;
// System.out.println(c);
// }
// }
//
// public void fun1(){
// Inner1 inner1 = new Inner1();
// inner1.show1();
// }
//
//}
静态成员内部类
1.格式:直接在定义内部类的时候加上static关键字
public class A{
static class B{
}
}
2.注意:
a.内部类可以定义属性,方法,构造等
b.静态内部类可以被final或者abstract修饰
被final修饰之后,不能被继承
被abstract修饰之后,不能new
c.静态内部类不能调用外部的非静态成员
d.内部类还可以被四种权限修饰符修饰
3.调用静态内部类成员:
外部类.内部类 对象名 = new 外部类.内部类()
public class Person {
public void eat(){
System.out.println("人要干饭");
}
static class Heart{
public void jump(){
System.out.println("心脏哐哐哐跳");
}
}
}
public class Test01 {
public static void main(String[] args) {
// 外部类.内部类 对象名 = new 外部类.内部类()
Person.Heart heart = new Person.Heart();
heart.jump();
}
}
非静态成员内部类
1.格式:直接在定义内部类的时候加上static关键字
public class A{
class B{
}
}
2.注意:
a.内部类可以定义属性,方法,构造等
b.静态内部类可以被final或者abstract修饰
被final修饰之后,不能被继承
被abstract修饰之后,不能new
c.静态内部类不能调用外部的非静态成员
d.内部类还可以被四种权限修饰符修饰
3.调用非静态内部类成员:
外部类.内部类 对象名 = new 外部类().new 内部类()
例子
public class Person {
public void eat(){
System.out.println("人要干饭");
}
class Heart{
public void jump(){
System.out.println("心脏哐哐哐跳");
}
}
}
public class Test01 {
public static void main(String[] args) {
// 外部类.内部类 对象名 = new 外部类().new 内部类()
Person.Heart heart = new Person(). new Heart();
heart.jump();
}
}
局部内部类
定义:
- 局部内部类是定义在方法或作用域内部的类。它就像是方法内部的一个局部变量,只不过这个 “变量” 是一个类。
例子
public class Person {
public void eat(){
class Heart{
public void jump(){
System.out.println("杨浩东真帅");
}
}
new Heart().jump();
}
}
public class Person {
public void eat(){
class Heart{
public void jump(){
System.out.println("心脏哐哐哐的跳");
}
}
new Heart().jump();
}
}
抽象类作为方法参数和返回值
1.抽象类作为方法参数传递,传递实参时,传递的是其子类对象
2.抽象类作为方法返回值类型返回时,实际返回的是其子类对象
public abstract class Animal {
public abstract void eat();
}
public class Dog extends Animal{
@Override
public void eat() {
System.out.println("狗啃骨头");
}
}
public class Test02 {
public static void main(String[] args) {
Dog dog = new Dog();
method01(dog);
System.out.println("=================");
Animal animal = method02();//Animal animal = new Dog()
animal.eat();
}
public static void method01(Animal animal){//Animal animal = dog
animal.eat();
}
public static Animal method02(){
return new Dog();
}
}
匿名内部类
定义
所谓的匿名内部类,可以理解为没有显式声明出类名的内部类
匿名内部类
语句定义格式:
new 类|抽象类|接口(){
方法的重写;
}
由JVM自己底层造了一个类去继承或者实现我们的类或者接口,我们只需要关注方法的重写逻辑就可以了,然后JVM把这个没有名字的类
造一个对应的对象。
特点
- 定义一个没有名字的内部类
- 这个类实现了父类,或者父类接口
- 匿名内部类会创建这个没有名字的类的对象
例子
abstract class Demo3{
public abstract void fun1();
}
//class Demo3Zi2 extends Demo3{
// @Override
// public void fun1() {
// System.out.println("张成阳真帅!");
// }
//}
//
//class Demo3Zi extends Demo3{
// @Override
// public void fun1() {
// System.out.println("好好学习,天天向上!");
// }
//}
class Demo3Test{
public void show1(Demo3 demo3){
demo3.fun1();
}
}
public class NiMingClassDemo1 {
public static void main(String[] args) {
Demo3Test demo3Test = new Demo3Test();
// demo3Test.show1(new Demo3Zi());
// demo3Test.show1(new Demo3Zi2());
demo3Test.show1(new Demo3() {
@Override
public void fun1() {
System.out.println("好好学习,天天向上!");
}
});
}
}
1.什么时候使用匿名内部类:
当简单调用一次接口中的方法,我们就可以使用匿名内部类
2.将一种格式代表实现类对象或者子类对象来看待,来学习
3.匿名内部类会编译生成的,咱们不要管,我们只需要利用咱们讲的格式去new对象,调用重写的方法即可
匿名内部类复杂用法_当参数传递
public interface USB {
void open();
}
public class Test01 {
public static void main(String[] args) {
method01(new USB() {
@Override
public void open() {
System.out.println("usb打开了");
}
});
}
public static void method01(USB usb){
usb.open();
}
}
匿名内部类复杂用法_当返回值返回
public interface USB {
void open();
}
public class Test02 {
public static void main(String[] args) {
USB usb = method01();
usb.open();
}
public static USB method01(){
return new USB() {
@Override
public void open() {
System.out.println("USB打开了");
}
};
}
}
标签:内部,void,public,static,new,class
From: https://www.cnblogs.com/03270925yhd/p/18680325