您的位置:首页 > 编程语言 > Java开发

Java学习-看完这一篇文章,了解内部类

2020-06-05 04:42 288 查看

今天给大家分享一下内部类的知识,内部类是Java中比较难理解的一部分内容。但如果理清楚了,其实很简单。
内部类的分类
内部类分为四类

  • 成员内部类
  • 静态成员内部类
  • 局部内部类
  • 匿名内部类

内部类是什么,就是类里面的类

成员内部类

成员内部类,和成员方法,成员变量的"地位"相似

public class Outer {
/**
* 成员变量
*/
public int Num = 100;
/**
* 成员方法
*/
public void f(){
System.out.println("外部类的成员方法被调用");
}
/**
* 成员内部类
*/
public class Inner{
public void method(){
System.out.println(Num);
f();	//这里可以看到,在内部类的成员方法中可以直接使用外部类的成员方法,
//也可以使用外部类的成员变量
}
}

public static void main(String[] args) {
/*
成员内部类的实例化
外部类.内部类 oi = new 外部类().new 内部类();
*/
Outer.Inner oi = new Outer().new Inner();
//调用内部类的成员方法
oi.method();
实例化的内部类对象只能调用内部类自己的成员变量成员方法,无法调用外部类的
}
}

成员内部类实例化
/*
成员内部类的实例化
外部类.内部类 oi = new 外部类().new 内部类();
*/

静态成员内部类

就是在成员内部类的前面加上static关键字

public class Outer {
/**
* 静态成员变量
*/
public static int number = 10;
/**
* 静态成员方法
*/
public static void staticMethod(){
System.out.println("静态方法被调用");
}

/**
* 静态成员类只能调用外部类的静态方法和静态变量
*/
public static class Inner{
public void method(){
System.out.println(number);
staticMethod();
}
}
public static void main(String[] args) {
/**
* 创建格式:外部类.内部类 oi = new 外部类.内部类();
*/
Outer.Inner oi = new Outer.Inner();
oi.method();
}
}

局部内部类

局部内部类是指在类的方法中创建类

public class Outer {
/**
* 成员变量
*/
public int Num = 100;

/**
* 成员方法
*/
public void f(){
System.out.println("外部类的成员方法被调用");
}

/**
*成员方法中定义一个成员内部类
*/
public void findInner(){
//局部内部类
class Inner{
//局部内部类的成员变量
int number;
//局部内部类的成员方法
public void method(){
//可以随便调用外部类的成员变量和方法
System.out.println(Num);
f();
}
}
/** 因为是局部内部类,只在方法中有用,所以不加修饰符
*  创建对象时,需要在方法内部创建
*/
Inner inner = new Inner();
inner.method();

}

public static void main(String[] args) {
Outer outer = new Outer();
/**
* 调用局部内部类,需要创建外部类对象,然后调用方法
*/
outer.findInner();
}
}

匿名内部类

匿名内部类也就是没有名字的内部类

正因为没有名字,所以匿名内部类只能使用一次,它通常用来简化代码编写

但使用匿名内部类还有个前提条件:必须继承一个父类或实现一个接口

  • 基于抽象类的内部类
基于抽象类的内部类
abstract class AbstractType {
abstract public void test();
}

class TypeA extends AbstractType {

@Override
public void test() {
System.out.println("一个类继承abstract修饰的类,完成abstract方法");
}
}

public class Demo1 {
public static void main(String[] args) {
TypeA typeA = new TypeA();
typeA.test();

/*
new AbstractType() {
// 这里是类的本体
}
这里不存在类名,但是该类的本体是一个类继承了abstract修饰的类可以
实现的类的本体。这里可以认为定义了的是一个abstract的一个子类
并且创建了一个abstract的子类对象,赋值给了abstract修饰的类的
引用数据类型变量
*/
AbstractType at = new AbstractType() {
@Override
public void test() {
System.out.println("匿名内部类的对象,调用方法");
}
};

at.test();

new AbstractType() {

@Override
public void test() {
System.out.println("匿名内部类的匿名对象。可以调用方法");
}
}.test();

testInnerType(typeA);

testInnerType(new AbstractType() {
@Override
public void test() {
System.out.println("匿名内部类对象,直接作为方法的参数使用!!!");
}
});
}

public static void testInnerType(AbstractType at) {
at.test();
}
}
  • 基于接口的内部类
2.基于接口的内部类
import java.util.Arrays;
import java.util.Comparator;

interface A {
public void testA();
}

public class Demo2 {
public static void main(String[] args) {
/*
这里定义的是一个接口A 的引用,指向的是一个接口的匿名内部类的对象
new A() 之后的大括号内容是一个类遵从接口A之后完成的代码
*/
A a = new A() {
@Override
public void testA() {
System.out.println("接口的匿名内部类对象");
}
};

a.testA();

new A() {

@Override
public void testA() {
System.out.println("接口匿名内部类的匿名对象,直接调用方法");
}
}.testA();

test(new A() {
@Override
public void testA() {
System.out.println("接口匿名内部类的匿名对象,直接作为方法的参数使用");
}
});

Person p1 = new Person(1, "无双剑姬");
Person p2 = new Person(2, "无极剑圣");
Person p3 = new Person(3, "疾风剑豪");
Person p4 = new Person(4, "影流之主");
Person p5 = new Person(5, "刀锋意志");
Person p6 = new Person(6, "瑞文");

Person[] arr = {p2, p1, p5, p4, p3, p6};

Arrays.sort(arr, new Comparator<Person>() {
@Override
public int compare(Person o1, Person o2) {
return o2.getId() - o1.getId();
}
});

System.out.println(Arrays.toString(arr));
}

public static void test(A a) {
a.testA();
}
}
//Person类
class Person {
private int id; //id
private String name;  //姓名

//构造方法
public Person() {
}
public Person(int id, String name) {
this.id = id;
this.name = name;
}
//成员变量的get和set方法
public int getId() {	return id;	}
public void setId(int id) {	this.id = id;	}
public String getName() { return name;	}
public void setName(String name) {	this.name = name;	 }

@Override
public String toString() {
return "Person{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}

@Override
public boolean equals(Object obj) {
System.out.println("equals被调用");
if (this == obj) {
return true;
}

if (!(obj instanceof Person)) {
return false;
}

Person p = (Person) obj;
return p.name.equals(this.name) && this.id == p.id;
}

@Override
public int hashCode() {
System.out.println("hashCode被调用");
return id;
}
}

这些代码希望大家可以自己动手敲一遍,有不懂得可以留言

内部类可以写链表,简化代码等作用

一道面试题…😊

下一篇分享一下接口和抽象类的区别

面试题答案😂,有其他方法的小伙伴在评论区留言

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: