java基础:内部类

内部类

1.简介:
大部分时候,类被定义为一个独立的程序单元,在某些情况下,也会把一个类放在另外一个类的内部定义,这种类就被称为内部类(嵌套类),包含内部类的类也被称为外部类(宿主类)

2.作用:

*内部类提供了更好的封装,可以将内部类隐藏在外部类之内,不允许同一个包中其他类访问该类。内部类只有在外部类中才有用

*内部类的成员可以直接去访问外部类的私有数据,因为内部类被当做外部类的成员变量,但是外部类不能访问内部类的实现细节(比如说内部类的成员变量)

*匿名内部类适合那些创建只使用一次的类

3.内部类和外部类的区别

*内部类比外部类可以多使用三个修饰符:private,protected,static 

*非静态内部类不能拥有静态成员(不能用static修饰)

 

非静态内部类

1.定义

定义方法其实很简单,就是把一个类放在另外一个类内部定义即可

public class OuterClass{
    //可以定义内部类
}

2.举个栗子

public class Cow {
    /**
     * 非静态内部类对象中寄生了内部类
     * 非静态类中不能有静态方法,静态成员变量,静态初始化块
     * */
    private double weight;
    public Cow(){}
    public Cow(double weight){
        this.weight=weight;
    }
    //定义非静态内部类
    private class CowLeg{
        private double length;
        private String color;
        public double getLength() {
            return length;
        }

        public void setLength(double length) {
            this.length = length;
        }

        public String getColor() {
            return color;
        }

        public void setColor(String color) {
            this.color = color;
        }
        public void info(){
            System.out.println("当前牛腿的颜色是:"+color+",高度为"+length);
            //访问外部类的私有属性
            System.out.println("本牛腿所在的奶牛重:"+weight);
        }
        public CowLeg(){}
        //定义构造器
        public CowLeg(double length,String color){
            this.color=color;
            this.length=length;
        }
    }

    public double getWeight() {
        return weight;
    }

    public void setWeight(double weight) {
        this.weight = weight;
    }
    public void test(){
        CowLeg c1=new CowLeg(1.12,"黑白相间");
        c1.info();
    }
    public static void main(String[]args){
        Cow cow=new Cow(378.9);
        cow.test();
    }
}

*外部类只能使用public 或者默认限定,但是内部类可以使用 public private protected和default(默认)进行限定

*通过上述例子也可以证明内部类可以直接访问外部类的private属性、

*其实每一个内部类中都包含着其外部类的引用!!!,所以在内存中才可以将内部类和外部类进行联系

 

静态内部类

1.简介:
如果使用static来修饰一个内部类,这个内部类属于外部类本身(类相关),而不属于外部类的某个对象(实例相关)。所以使用static修饰的内部类称为静态内部类,也被称为类内部类。

2.使用原则:
静态内部类可以包含静态成员,也可以包含非静态成员。因为静态成员不能去访问非静态成员,所以静态内部类不能去访问外部类的实例成员,只能访问外部类的static成员

3.举个栗子:
 

/**
 * static的作用是把类的成员变成类相关而不是实例相关(对象相关)
 * 使用static修饰内部类后,静态内部类可以包含静态成员,也可以包含非静态成员。静态内部类不能访问外部类的实例成员(只能访问类成员)
 *
 * 类属性:
 * 实例属性:
 *
 */
public class StaticInnerClass {
    private static int static_num = 1;
    private int no_static_num = 2;

    static class innerClass {
        public void showStaticNum() {
            System.out.println("get static num" + static_num);
        }

        public void showNum() {
            //error
            //System.out.println(no_static_num);
        }
    }

    public static void main(String[] args) {
        StaticInnerClass.innerClass innerClass = new StaticInnerClass.innerClass();
        innerClass.showStaticNum();

    }

}

*java允许在接口内定义内部类,接口中定义的内部类默认使用public static修饰(接口内部类只能是静态内部类,接口内部默认为public访问权限)

 

匿名内部类

1.使用条件:
匿名内部类必须要继承一个父类或者实现一个接口,但是最多只能继承一个父类或者实现一个接口

*匿名内部类不能是抽象类,系统在创建匿名内部类的时候会自动创建对象

*匿名内部类没有类名 不能定义构造器,但是可以定义初始化块来完成构造器需要做的事情

 

2.举个栗子

使用接口的匿名内部类

/**
 * 使用匿名内部类
 * 1.必须继承一个父类或者实现一个接口,但是最多只能继承一个父类或者实现一个接口
 * 2.匿名内部类不能是抽象类,系统在创建匿名内部类时,会立即创建匿名内部类的对象
 * 3.匿名内部类不能定义构造器,因为是匿名的 没有类名
 * 4.在java8开始之前,java被要求局部内部类。匿名内部类访问的局部变量必须使用final修饰,在java8之后,自动化
 */
interface Product {
    public double getPrice();

    public String getName();
}

public class AnnoymousTest {
    public void test(Product p) {
        System.out.println("购买了一个" + p.getName() + ",花掉了" + p.getPrice());
    }

    public static void main(String[] args) {
        AnnoymousTest ts = new AnnoymousTest();
        /**
         * 使用匿名内部类
         * */
        /**
         * product只是一个接口,无法直接创建对象
         * 如果只是要使用一个 可以使用匿名内部类
         * 匿名内部类只有一个隐式的无参构造器
         *
         *
         * c
         * */
        ts.test(new Product() {
            @Override
            public double getPrice() {
                return 88.88;
            }

            @Override
            public String getName() {
                return "商品名";
            }
        });
        /**
         * 使用内部类
            replaceCode
         * */
        class AnoymousProduct implements Product {

            @Override
            public double getPrice() {
                return 0;
            }

            @Override
            public String getName() {
                return null;
            }
        }

    }
}

继承父类(abstract)的匿名内部类

/**
 * 待继承的父类
 * */
abstract class Device{
    private String name;
    public abstract double getPrice();
    public Device(){}
    public Device(String name){
        this.name=name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
public class AnonymousInner {
    public void test(Device d){
        System.out.println("购买了一个"+d.getName()+",花掉了"+d.getPrice());
    }
    public static void main(String[]args){
        AnonymousInner ai=new AnonymousInner();
        /**
         * 使用匿名内部类
         * */
        ai.test(new Device("toy") {
            @Override
            public double getPrice() {
                return 66.6;
            }
        });
        /**
         * replaceCode
         * */
        Device device=new Device() {
            //初始化块
            {
                System.out.println("匿名内部类的初始化块");
            }
            @Override
            public double getPrice() {
                return 66.6;
            }
            /***
             *重写方法
             */
            public String getName(){
                return"toy2";
            }
        };
        ai.test(device);
    }
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值