文章目录
- 1.内部类概述
- 2.特点
- 3.练习 : 内部类入门案例
- 4.成员内部类
-
- 4.1 练习 : 被private修饰
- 4.2 练习 : 被static修饰
- 5.局部内部类
- 6.匿名内部类
1.内部类概述
如果一个类存在的意义就是为指定的另一个类,可以把这个类放入另一个类的内部。
就是把类定义在类的内部的情况就可以形成内部类的形式。
A类中又定义了B类,B类就是内部类,B类可以当做A类的一个成员看待
2.特点
- 内部类可以直接访问外部类中的成员,包括私有成员
- 外部类要访问内部类的成员,必须要建立内部类的对象
- 在成员位置的内部类是成员内部类
- 在局部位置的内部类是局部内部类
3.练习 : 内部类入门案例
package partFour;
/*本类用作内部类的入门案例*/
public class TestInner1 {
public static void main(String[] args) {
//3.1创建内部类的对象,使用内部类的资源
/*外部类名.内部类名 对象名=外部类对象.内部类对象*/
Outer.Inner oi = new Outer().new Inner();
//3.2通过创建好的内部类对象,使用内部类的资源
oi.delete();
System.out.println(oi.sum);
//3.3外部想要使用外部类的资源,需要用过外部类的对象
new Outer().play();
}
}
//1.创建外部类
class Outer{
//1.1创建外部类的成员变量
String name;
private int age;
//1.2创建外部类的成员方法
public void play(){
System.out.println("Outer...play()");
//5.外部类使用内部类资源
//delete(); //不可以直接调用内部类的方法
//System.out.println(sum);//不能直接查看内部类的属性
/*外部类如果想要使用内部类的资源,必须先创建内部类的对象
* 通过内部类对象调用内部类的功能*/
Inner in = new Inner();//直接创建内部类对象,无需指定外部类,已经在外部类里了
System.out.println(in.sum);//通过内部类对象查看内部类的属性
in.delete();//通过内部类对象调用内部类的方法
}
//2.创建内部类--被看做外部内的特殊成员
class Inner{
//2.1 定义内部类的成员变量
int sum = 10;
//2.2 定义内部类的成员方法
public void delete(){
System.out.println("Inner...delete()");
//4.测试内部类能否使用外部类的资源
//play();//可以调用外部类的方法
/*要注意,play与delete只能同时调用一个,不然外部类与内部类容易形成死循环*/
System.out.println(name);//可以查看外部类的普通属性
System.out.println(age);//可以查看外部类的私有属性
}
}
}
4.成员内部类
4.1 练习 : 被private修饰
package partFour;
/*本类用于测试成员内部类被private修饰*/
public class TestInner2 {
public static void main(String[] args) {
//4.创建内部类对象
//Outer2.Inner2 oi = new Outer2().new Inner2();
//oi.eat();
/*如果成员内部类被private修饰,外部无法直接访问,或创建内部类的对象*/
//7.间接访问,虽然创建不了私有内部类的对象,但是可以创建外部类的对象
new Outer2().getInner2Eat();
}
}
//1.创建外部类
class Outer2{
//6.提供一个公共的方法,在方法内部创建内部类Inner2的对象,调用内部类的功能
public void getInner2Eat(){
Inner2 in = new Inner2();//可以在外部类里创建私有成员内部类的对象
in.eat();//通过创建好的内部类对象调用内部类的功能
}
/*成员内部类的位置在类里方法外*/
public Object Inner2;
//2.创建成员内部类Inner2
private class Inner2{
//3.创建成员内部类的普通方法
public void eat(){
System.out.println("Inner...eat()");
}
}
}
总结:
成员内部类被Private修饰以后,无法被外界直接创建创建对象使用
所以可以创建外部类对象,通过外部类对象间接访问内部类的资源
4.2 练习 : 被static修饰
package partFour;
/*本类用于测试成员内部类被static修饰*/
public class TestInner3 {
public static void main(String[] args) {
//4.1创建内部类对象,访问内部类资源 方式一
//Outer3.Inner3 oi = new Outer3().new Inner3();
//oi.show();//Inner3...show()
//4.2创建内部类匿名对象访问内部类资源 方式二
//new Outer3().new Inner3().show();//Inner3...show()
/*现象:当内部类被static修饰以后,new Outer3报错,注释掉上面的代码*/
//6.1由于内部类是静态的,所以可以通过外部类类名直接找到,不用创建外部类对象
Outer3.Inner3 oi = new Outer3.Inner3();
oi.show();
//6.2静态成员内部类创建匿名对象
new Outer3.Inner3().show();
//8.1调用内部类的静态方法:方式一 不推荐
new Outer3.Inner3().show2();
//8.1调用内部类的静态方法:方式二
/*没有创建任何一个对象,直接都是通过类名找到的静态资源
* 像这样连着点的方式,称作:链式加载*/
Outer3.Inner3.show2();
}
}
//1.创建外部类
class Outer3{
//2.创建成员内部类
//5.用static修饰成员内部类
static class Inner3{
//3.定义成员内部类的普通方法
public void show(){
System.out.println("Inner3...show()");
}
//7.创建一个静态成员内部类中的静态方法
static public void show2(){
System.out.println("Inner...show2()");
}
}
}
总结:
静态资源访问时不需要创建对象,可以通过类名直接访问
访问静态类中的静态资源可以通过”. . . ”链式加载的方式访问
5.局部内部类
package partFour;
/*本类用于测试局部内部类*/
public class TestInner4 {
public static void main(String[] args) {
//5.创建外部类的对象,调用外部类的show方法
new Outer4().show();
//new Outer4().new Inner4();//会报错
/*如何使用局部内部类的资源呢?
* 创建外部类对象调用外部方法或者直接在main()创建局部内部类对象都是不可行的
* 需要在外部类中创建内部类的对象,并且调用内部类的方法,才会触发内部类的功能*/
}
}
//1.创建外部类
class Outer4{
//2.创建外部类成员方法
public void show(){
System.out.println("Outer...show()");
/*局部内部类的位置:在方法里*/
//3.创建局部内部类
class Inner4{
//4.创建局部内部类的资源
String name;
int age;
public void eat(){
System.out.println("Inner...eat()");
}
}
/*如何使用局部内部类的资源*/
//6.在show()里面创建内部类对象,调用内部类的功能
Inner4 in = new Inner4();
in.eat();
System.out.println(in.name);
System.out.println(in.age);
}
}
6.匿名内部类
package partFour;
/*本类用于测试匿名内部类
* 匿名内部类没有名字,通常与匿名对象结合在一起使用*/
public class TestInner5 {
public static void main(String[] args) {
//传统方法:创建接口的实现类+实现类实现类实现接口中的抽象方法+创建实现类对象+通过对象调用方法
//3.创建接口一对应的匿名对象与匿名内部类new Inter1(){}.save;,并调用实现了的方法save
new Inter1() {
@Override
public void save() {
System.out.println("save()...");
}
@Override
public void get() { }
}.save();
//5.创建抽象类对应的匿名对象与匿名内部类
new Inter2(){//抽象类不能实现抽象方法,所以只实现了未实现的方法
@Override
public void drink() {
System.out.println("一人我饮酒醉");
}
}.drink();
//7.调用普通类的功能调用,创建匿名对象直接调用
new Inter3().powerUP();
new Inter3().powerUP();//new了俩次,所以是俩个匿名对象
/*如果想要多次使用实现后的功能,还是要创建普通的对象
* 匿名对象只能使用一次,一次只能调用一个功能
* 匿名内部类其实就充当了实现类的角色,去实现未实现的抽象方法,只是没有名字而已*/
Inter3 in = new Inter3();
in.study();
in.study();
in.study();
in.study();
}
}
//1.创建接口
interface Inter1{
//2.定义接口中的抽象方法
void save();
void get();
}
//4.创建抽象类
abstract class Inter2{
public void play(){
System.out.println("Inner...play()");
}
abstract public void drink();
}
//6.创建普通类
class Inter3{
public void study(){
System.out.println("什么都阻挡不了我学习");
}
public void powerUP(){
System.out.println("我们会越来越强的");
}
}
总结:
匿名内部类属于局部内部类,而且是没有名字的局部内部类,通常和匿名对象一起使用