华为ICT培训-高端面授华为ICT培训机构
云和教育:云和数据集团高端IT职业教育品牌
  • 华为
    授权培训中心
  • 腾讯云
    一级认证培训中心
  • 百度营销大学
    豫陕深授权运营中心
  • Oracle甲骨文
    OAEP中心
  • Microsoft Azure
    微软云合作伙伴
  • Unity公司
    战略合作伙伴
  • 普华基础软件
    战略合作伙伴
  • 新开普(股票代码300248)
    旗下丹诚开普投资
  • 中国互联网百强企业锐之旗
    旗下锐旗资本投资

JAVA大咖分享:深入剖析JAVA内部类

  • 发布时间:
    2020-08-20
  • 版权所有:
    云和教育
  • 分享:
什么是内部类?
概念:定义在类中的类
怎么用的?
就像在类中定义属性一样修饰符 class 类名{}第一:内部类相当于是外部类中的一个属性第二:内部类本身也就是一个类,跟正常的类一样
为什么要用它?
类的生命周期程序运行时开始到程序结束时销毁,但是呢,某些情况下,在整个应用程序中对该类的使用频率较低,那此时就需要将其定义为内部类,以缩短其生命周期;简单点来说:缩短类的生命周期划分:内部类、局部内部类、匿名内部类使用场景:当类或该类的对象并不是很常用的时候,就可以定义为内部类
内部类
java
public class Outer {public int count;//内部类也相当于是外部类中的一个成员变量
class Inner{
public int count;
public void show() {
System.out.println("inner show");
}
}
}
//思路:1、把内部类当成是外部类中的一个成员,那么想要找到内部类就需要有外部类的对象
//2、show方法需要对象进行调用的,而内部类的对象又需要外部类的对象进行调用
//3、外部类.内部类 变量名 = 外部类对象.内部类对象
//4、Outer.Inner inner = new Outer().new Inner();
public static void main(String[] args) {
Outer outer = new Outer();
System.out.println(outer.count);
//创建内部类对象
Outer.Inner inner = outer.new Inner();
inner.show();
}
 
内部类和不同的修饰同时存在时的特点:

java
public class Outer {//对于该成员变量,其生命周期和对象的生命周期一致,作用域在整个类中都可以使用,调用形式:使用对象调用
//可用的修饰符:public private protected static final
private int count;//private修饰后,该类就只能在当前类中使用
//static修饰后,该类的生命周期和外部类的生命周期一致,就失去了内部类本身的意义
//final修饰后,该类无法被继承
class Inner{
private int count;
public void show() {
System.out.println("inner show");
}
}
}
//调用
Outer.Inner inner = new Outer.Inner();
inner.show();
Outer outer = new Outer();
Outer.Inner inner = outer.new Inner();
inner.show();
 
注意:内部类可以调用外部类的属性和方法,但是外部类只能通过对象的形式去调用内部类中的属性和方法。

java
//在内部类中区分this关键词的所属
public class Outer {
private int count = 6;
//内部类也相当于是外部类中的一个成员变量
class Inner{
public int count = 5;
public int num;
public void show() {
int count = 4;
System.out.println("inner show "+ Outer.this.count);
}
}
public void method() {
Inner inner = new Inner();
inner.show();
}
}

局部内部类:定义在方法中的类,生命周期和方法的生命周期一致,作用域只在方法中
java
public class Outer2 {
/**
* jdk1.8中内部类所在的方法中的参数默认是final修饰的
* jdk1.7及之前需要明确标出final
* @param count
*/
public void method(int count) {
int a = 1;
//count++;
class Inner{
public void show() {
System.out.println("show "+count);
}
}
new Inner().show();
}
public static void main(String[] args) {
Outer2 outer = new Outer2();
outer.method(1);
}
}
匿名内部类:没有具体的子类名字
例如:User user = new User();   new User(); 有名字的话可以多次使用
概念:没有名字的内部类,没名字说明不经常用,内部类作用是为了缩短生命周期
例如:老王家生了个孩子起名叫小王,过段时间他老婆又怀了一个,叫老王家的孩子,他是没有名字,所以只能通过其父亲的名字来区别,因此,匿名内部类必须要有继承或实现;
语法:父类类名 名字 = new 父类类型(){};
注意:new 父类类型(){}相当于就是一个子类对象
学习时只需要记住三个点:
1、记住语法
2、new 父类类型(){}相当于就是一个子类对象,只是没有名字
3、父类类名 名字 = new 父类类型(){};是多态形式,向上转型
java
public interface ItemDao{
public int delUser(int uid);
}
public static void main(String[] args){
new ItemDao(){
@Override
public int delUser(int uid){}
}.delUser(1);
}
//上述形式,相当于创建了一个子类去实现了ItemDao接口并重写方法
public class ItemDaoImpl implements ItemDao{
@Override
public int delUser(int uid){}
}
//单独创建一个类去实现接口和使用匿名内部类实现接口的区别是:使用匿名内部类可节约资源-生命周期短
 
思考:根据上述匿名内部类的调用形式上发现一个问题,如果其中重写了多个方法时,如何调用?
回答:匿名内部类可以使用其父类来进行接收
java
public interface ItemDao{
public int delUser(int uid);
public int insertUser();
}
public static void main(String[] args){
ItemDao itemDao = new ItemDao(){
@Override
public int delUser(int uid){}
@Override
public int inserUser(){}
};
itemDao.delUser(1);
itemDao.inserUser();
}
思考:根据上述的使用方案,匿名内部类本身也是一个类,那也可以有自己特有的方法,如何调用呢?
回答:当子类有自己的特有方法时也就意味着该类应该被定义成一个单独的类存在
java
public interface ItemDao{
public int delUser(int uid);
public int insertUser();
}
public static void main(String[] args){
ItemDao itemDao = new ItemDao(){
@Override
public int delUser(int uid){}
@Override
public int inserUser(){}
public void show(){}
};
itemDao.delUser(1);
itemDao.inserUser();
//itemDao.show();
}
练习题:
java
public interface IUserDao{
public void speak();
}
public static void main(String[] args){
Object obj = new IUserDao(){
@Override
public void speak(){
Syso("speak");
};
};
obj.speak();
IUserDao userDao = new IUserDao(){
@Override
public void speak(){
Syso("speak");
};
};
userDao.speak();
}
文/云和数据java高级开发工程师代老师