内部类的基本概念
public class Demo{
public static void main(String args[]){
Outside out=new Outside();
out.fun();
}
}
class Outside{
private String info="outside";
public void fun(){
Interior in=new Interior();
in.print();
System.out.println(in.info);//访问内部类的私有属性
}
class Interior{
private String info="interior";
public void print(){
System.out.println(Outside.this.info);//访问外部类的私有属性
}
}
}
它破坏了程序的结构,但是他的优势是什么,如果没有就可以将类拿到外部:
public class Demo{
public static void main(String args[]){
Outside out=new Outside();//实例化外部类
out.fun();
}
}
class Outside{ //外部类
private String info="outside";
public String getInfo(){
return info;
}
public void fun(){
Interior in=new Interior(this);//实例化内部类对象
in.print();//调用内部类
}
//思考一:如果不是必要,就不使用内部类,被类外部访问info需要有getter方法
}
class Interior{ //类中定义的内部类
//思考三:如果想使用Outside类中的私有属性,需要用getter方法。实例化这个类时应该实例一个外部类的引用
private Outside out;
//思考四:通过interior类对象构造方法获取Outside类对象
public Interior(Outside out){
this.out=out;
}
public void print(){
//思考二:调用外部类中的getter方法,需要实例化Outside类。但是主类中已经new了一个对象了,这里实例化第二个Outside不好
System.out.println(this.out.getInfo());//调用外部属性
}
}
那么他的作用:是为了可以很方便的访问外部类的私有属性。同时内部类也可以访问外部类的私有属性
……那为什么要定义分开的两个类?根据紧耦合松内聚的做法,在一个类中编写就好了吧?防止内容太多故意分开的?……骚操作?(嘀咕)
内部类的相关说明
生成.class文件时,内部类的格式为:
外部类.内部类 内部对象 =new 外部类().new 内部类()
内部类.class文件名:Outside$Interior.class( $ 在程序中会换成 . )
所以!
public class Demo{
public static void main(String args[]){
Outside.Interior in=new Outside().new Interior();
in.print();
}
}
class Outside{
private String info="outside";
class Interior{
public void print(){
System.out.println(Outside.this.info);//访问外部类的私有属性
}
}
}
如果此时Interior类只允许Outer类使用,就可以使用private修饰Interior类,进行私有定义:
class Outside{
private String info="outside";
private class Interior{
public void print(){
System.out.println(Outside.this.info);//访问外部类的私有属性
}
}
}
此时Interior类不允许外部使用。
那么同理,内部接口:
public class Demo{
public static void main(String args[]){
IChannel channel=new ChannelImpl();
channel.send(((ChannelImpl)channel).new MessageImpl());
}
}
interface IChannel{
public void send(IMessage msg);
interface IMessage{
public String content();
}
}
class ChannelImpl implements IChannel {
public void send(IMessage msg){
System.out.println("send Message:"+msg.content());
}
class MessageImpl implements IMessage{
public String content(){
return "MessageImpl";
}
}
}
内部抽象方法:
public class Demo{
public static void main(String args[]){
IChannel channel=new ChannelImpl();
channel.send();
}
}
interface IChannel{
public void send();
abstract class AMessage{
public abstract String content();
}
}
class ChannelImpl implements IChannel {
public void send(){
AMessage msg=new MessageImpl();
System.out.println("send Message:"+msg.content());
}
class MessageImpl extends AMessage{
public String content(){
return "MessageImpl";
}
}
}
jdk1.8之后,接口中追加了static。那么,接口内部进行接口实现:
public class Demo{
public static void main(String args[]){
IChannel channel=IChannel.getChannelImpl();
channel.send();
}
}
interface IChannel{
public void send();
class ChannelImpl implements IChannel{
public void send(){
System.out.println("send message!");
}
}
public static ChannelImpl getChannelImpl(){
return new ChannelImpl();
}
}
这在类库中会经常见到……
static定义内部类
如果用static定义内部类,内部类就变成了外部类
static内部类只能访问外部类中的static成员
class Outside{
private static String info="outside";
static class Interior{
public void print(){
System.out.println(Outside.info);//访问外部类的私有属性
}
}
}
此时Interior类是一个独立的类,要实例化Interior类,只需要“外部类.内部类()”例:Outside.Interior in=new Outside.Interior();
static内部定义接口属于一组相关定义。static内部接口出现形式较多。
public class Demo{
public static void main(String args[]){
IMessage.send(new MessageCollect(),new ChannelContect());
}
}
interface IMessage{
static interface IMessageCollect{
public String getContent();
}
static interface IChannelContect{
public boolean connect();
}
public static void send(IMessageCollect mc,IChannelContect cc){
if(cc.connect()){
System.out.println(mc.getContent());
}else{
System.out.println("connect fail");
}
}
}
class MessageCollect implements IMessage.IMessageCollect{
public String getContent(){
return "i am ok!";
}
}
class ChannelContect implements IMessage.IChannelContect{
public boolean connect(){
return true;
//return false;
}
}
方法中定义内部类
内部类可以在任意结构中定义,包括:类中,方法中,代码块中。方法中定义内部类的形式较多。
public class Demo{
public static void main(String args[]){
new Outer().fun(20210101L);
}
}
class Outer{
private String msg="outer";
public void fun(long time){
class Inner{
public void print(){
System.out.println(Outer.this.msg);
System.out.println(time);
//方法中参数的直接访问是从jdk1.8开始支持的。jdk1.8之前若要访问,参数前必须追加final(fun(final long time)或final String str;)
//这是为函数式编程准备的功能
}
}
new Inner().print();
}
}
匿名内部类
匿名内部类是简化的内部类,主要是在抽象类或接口的子类上实现的。(并不是只在抽象借口类中,只是在抽象接口中才有意义。)
匿名内部类的使用:
利用静态方法做一个匿名内部类
public class Demo{
public static void main(String args[]){
IMessage msg=new IMessage(){
public void send(){
System.out.println("send message");
}
};
msg.send();
}
}
interface IMessage{
public void send();
}
在接口中直接定义匿名内部类
public class Demo{
public static void main(String args[]){
IMessage.getInstance().send();
}
}
interface IMessage{
public void send();
public static IMessage getInstance(){
return new IMessage(){
public void send(){
System.out.println("send");
}
};
}
}
与内部类相比,匿名内部类只是一个没有名字的只能使用一次的,并且结构固定的子类操作。