内部类
什么情况下外部不能够创建类的对象:
1.抽象类
2.接口
3.构造方法全部私有
4.内部类
内部类的引入:
提高了类的安全性
内部类的概念:
将类定义类的内部,那么该类就成为内部类
注意: 内部类是一个相对的概念:
如果A类中有一个B类,那么A类相对于B类来说就是外部类,那么B类相对于A类来说就是内部类
内部类的分类
1.局部内部类
2.成员内部类
3.静态内部类
4.匿名内部类
内部类的特点:
1.内部类可以直接访问外部类的私有成员吗? 可以
2.外部类可以访问内部类的成员? 必须创建内部类的对象
3.如果编译器编译生成字节码文件,那么内部类会不会生成.class文件,如果会的话,格式是?
会生成,格式是 : 外部类类名$内部类类名.class
4.如果在外界要访问内部类对象可以,可以是可以,但是内部类有一个缺陷,会造成类和类的耦合性过高,慎用
举例代码如下:
public class InnerClassDemo01 {
public static void main(String[] args) {
}
}
class Outer{
private int num = 10;
// 成员内部类
class Inner{
public int num2 = 20;
public void show() {
System.out.println(num);
}
}
public void test() {
Inner inner = new Inner();
System.out.println(inner.num2);
inner.show();
}
// 静态内部类
static class Inner2{
}
public void show() {
// 局部内部类
class Inner3{
}
// 匿名内部类
new Inter() {
@Override
public void show() {
System.out.println("show");
}
}.show();
new Inter() {
@Override
public void show() {
System.out.println("show2");
}
};
}
}
interface Inter {
void show();
}
成员内部类
格式:
外部类类名.内部类类名 对象 = new 外部类对象.new 内部类对象
一旦内部类成员加上private关键字,外界无法访问
当外部类类名和内部类类名成员重名的时候如何访问?
外部类类名.this.外部类成员
1.内部类如何访问外部类成员 – 直接访问
2.外部类如何访问内部类成员 – 不能直接访问,创建内部类对象
3.外界如果访问内部类成员
外部类类名.内部类类名 对象 = new 外部类对象.new 内部类对象
4.外界如何访问内部类私有成员
无法访问,可以内部类提供对外的公共访问方式
5.当外部类类名和内部类类名成员重名的时候如何访问 – 外部类类名.this.外部类成员
举例代码如下:
public class InnerClassDemo02 {
public static void main(String[] args) {
// Outer2 outer2 = new Outer2();
// Outer2.Inner oi = new Outer2().new Inner();
// System.out.println(oi.num);
// System.out.println(outer2.num);
Outer2.Inner oi = new Outer2().new Inner();
oi.show();
}
}
class Fu {
int num = 5;
}
class Outer2 extends Fu{
int num = 10;
// 成员位置
class Inner{
int num = 20;
public void show() {
int num = 30;
System.out.println(num); // 30
System.out.println(this.num); // 20
System.out.println(Outer2.this.num); // 10
System.out.println(Outer2.super.num); // 5
}
}
public void show() {
}
}
举例2代码如下
/*
* 使用private修饰成员内部类的案例
*
* 设计 一个电脑 有 CPU 一个身体有心脏
*/
public class InnerClassDemo03 {
public static void main(String[] args) {
Body body = new Body();
body.setHeart();
}
}
class Body {
private int age;
private boolean isDoctor = true;
private class Heart {
private int blood;
public void operateHeart() {
System.out.println("心脏小手术");
}
}
public int getAge() {
return age;
}
public void setAge(int age) {
if (age < 0 || age > 100) {
System.out.println("年龄不在我想要活的范围内");
} else {
this.age = age;
}
}
public void setHeart() {
if (isDoctor) {
Heart heart = new Heart();
heart.operateHeart();
} else {
System.out.println("再动我报警了!!!");
}
}
public boolean isDoctor() {
return isDoctor;
}
public void setDoctor(boolean isDoctor) {
this.isDoctor = isDoctor;
}
}
局部内部类
在局部位置创建内部类对象,访问内部类成员
在JDK1.8之前,如果局部内部类访问外部类成员,需要加final关键字
举例代码如下:
public class InnerClassDemo04 {
public static void main(String[] args) {
Outer3 o = new Outer3();
o.show();
}
}
class Outer3 {
int a = 20;
public void show() {
int x = 100;
class InnerX {
int num = 10;
public void show() {
System.out.println(num);
System.out.println(a);
}
}
InnerX innerX = new InnerX();
System.out.println(innerX.num);
innerX.show();
}
public void method() {
}
}
静态内部类
格式:
外部类类名.内部类类名 对象 = new 外部类对象.内部类类名();
静态内部类中可以有静态成员和非静态成员
访问非静态成员需要创建对象
访问静态成员可以直接调用
外部类类名.内部类类名.静态成员
方便访问静态内部类的成员
举例代码如下:
public class InnerClassDemo05 {
public static void main(String[] args) {
// 外部类类名.内部类类名 对象 = new 外部类对象.new 内部类对象
// 外部类类名.内部类类名 对象 = new 外部类对象.内部类类名();
Outer4.Inner oi = new Outer4.Inner();
System.out.println(oi.num);
System.out.println(oi.num2);
oi.show();
oi.method();
Outer4.Inner.num2 = 200;
Outer4.Inner.method();
}
}
class Outer4 {
static class Inner {
public int num = 10;
public void show() {
System.out.println("Outer4.Inner.show()");
}
public static int num2 = 20;
public static void method() {
System.out.println("Outer4.Inner.method()");
}
}
interface Entry {
}
}
匿名内部类
概念:
本质就是一个子类匿名对象
特点:
1.是一个子类匿名对象
父类 可以是 普通类 抽象类 接口
2.是一个对象
3.没有名字的子类
前提条件: 存在一个父类(接口 /抽象类/普通类)
格式:
没有对象名
没有类名
当时它是一个子类
还是一个对象
new 类名/接口名(){
//重写方法
}
举例代码如下:
public class InnerClassDemo06 {
public static void main(String[] args) {
new Student() {
};
new AbsTeacher() {
@Override
void teach() {
// TODO Auto-generated method stub
}
};
new ICar() {
@Override
public void run() {
// TODO Auto-generated method stub
}
};
IDailup dailup = new IDailup() {
@Override
public void show2() {
// TODO Auto-generated method stub
}
@Override
public void show() {
// TODO Auto-generated method stub
}
};
dailup.show();
dailup.show2();
}
}
class CarImpl implements ICar{
@Override
public void run() {
System.out.println("CarImpl.run()");
}
}
interface ICar {
void run();
}
interface IDailup{
void show();
void show2();
}
abstract class AbsTeacher{
abstract void teach();
}
class Student{
public void show() {
System.out.println("Student.show()");
}
}
回顾类的组成:
类的组成
包的声明 package;
包的导入 import;
[访问权限修饰符] class 类名 extends 父类(普通类,抽象类) implements 接口 {
成员变量
常量
1.字面值常量
2.自定义常量
类变量
构造代码块
构造方法
1.无参构造方法
2.全参构造方法
成员方法
1.普通方法
2.get/set读写方法
抽象方法
类方法
内部类
1.成员内部类
2.静态内部类
3.局部内部类
4.匿名内部类
内部接口
静态代码块
局部代码块