1.11:面向对象(下)

前言:菜鸟一枚,如有问题欢迎大家在评论区指出,我们一起学习。

1.11.1:常量与枚举

        在实际开发过程中,某些类型的对象是有限的几个,那么我可以考虑使用常量。在java中,我们有三种方式实现常量,这三种方式各有千秋。

第一种方式:将常量放在类中

1.使用 private  修饰构造器,使其不能被实例化和被继承

2.定义 static final 类型的成员变量,即常量

public class Constants {

    public static final String APP_NAME = "MyApplication";


    public static final int MAX_USERS = 100;

    private Constants(){}


}

第二种方法: 接口中定义常量

接口中成员变量默认是 static final 修饰的常量

public interface Constants{
   int SUCCESS = 1;
   int ERROR = 2;
}

注意: 接口定义的常量虽然不可修改,但是接口允许被实例化,并且接口中不能定义静态代码块。

 第三种方法:使用枚举类定义常量

1.使用 enum 关键字(jdk1.5之后)

2.定义常量类(jdk1.5之前)

 jdk1.5之前的枚举类:

//jdk1.5之前的枚举类
public class Season {
    //第二步:本类内部创建一组常量对象,并添加public static修饰符,对外暴露这些常量对象
    public static final Season SPRING = new Season("春季");
    public static final Season SUMMER = new Season("夏季");
    public static final Season AUTUMN = new Season("秋季");
    public static final Season WINTER = new Season("冬季");
    private String info;

    private Season() {
    }


    //第一步:私有所有的构造器(限制外部类随意创建对象并禁止继承)
    private Season(String info) {
        this.info = info;
    }

    //第三步:对外提供get方法
    public String getInfo(){
        return this.info  
    }

}

当然,我们也可以重写toString方法, 打印对象的时候,我们能直接打印对应常量的值

jdk1.5之后定义的枚举类:使用 enum 关键字

public enum Season {
    //enum声明的枚举类必须在类体的第一部分给出若干本类的属性
    //不同jdk1.5之前的枚举类,enum声明的枚举类省略了public static final Seanson类,构造器,因为默认值就是它,写和不写都是它
    SPRING("春季"),SUMMER("夏季"),AUTUMN("秋季"),WINTER("冬季");

    private String info;
//enum声明的枚举类所有的构造器默认都是私有的,并且只能使私有的,省略了private修饰,所以它不允许其他类实例化
    Season() {
    }

    Season(String info) {
        this.info = info;
    }

//提供公开的get方法
    public String getInfo(){
        return this.name
    }


    @Override
    public String toString() {
        return this.info;
    }
}

枚举类型常用方法:

1.String toString(): 默认返回的是常量名(对象名),可以继续手动重写该方法!
2.String name():返回的是常量名(对象名)
3.int ordinal():返回常量的次序号,默认从0开始
4.枚举类型[] values():返回该枚举类的所有的常量对象,返回类型是当前枚举的数组类型,是一个静态方法
5.枚举类型 valueOf(String name):根据枚举常量对象名称获取枚举对象 

public class TestSeason {
    public static void main(String[] args) {
        Season season1 = Season.SPRING;
        //父类ENUM类默认重写了toString()方法
        System.out.println(season1);
        System.out.println(season1.name());
        //发现season1有下标
        System.out.println(season1.ordinal());
        System.out.println("--------------------------------");
        Season[] seasons = Season.values();//返回枚举类所有枚举值数组
        for (int i = 0; i < seasons.length; i++) {
            System.out.println(seasons[i]);
        }
        System.out.println("-----------------");
        Season season2 = Season.valueOf("SPRING");//根据属性名返回枚举对象
        System.out.println(season2);

    }
}

容易混淆的点:

1.抽象类不能被实例化,但是内部有公开的构造器供子类调用

2.接口不能被实例化,并且内部没有构造器

3.枚举不能被实例化,但是内部有供自己调用的私有构造器 

1.11.2:包装类

        Java提供了两个类型系统,基本类型与引用类型,使用基本类型在于效率,然而当要使用只针对对象设计的API或新特性(例如泛型),那么基本数据类型的数据就需要用包装类来包装。

装箱和拆箱: 装箱,把基本数据类型转为包装类对象。拆箱:把包装类对象拆为基本数据类型。

public class Test {
    public static void main(String[] args) {
        //装箱:将基础类型封装为引用类型
        int one = 100;
        Integer integer = new Integer(one);
        Integer integer1 = Integer.valueOf(one);
        //拆箱:将包装类对象转为基础数据类型
        int two;
        two = integer1.intValue();
        System.out.println(two);

        //jdk1.5之后可以自动装箱和拆箱
        //拆箱
        int three = new Integer(one);
        //装箱
        Integer integer2 = one;

        int four = integer2;
        System.out.println(four);
    }
}

 注意:JDK1.5以后,可以自动装箱和拆箱。

包装类缓存对象: 数据在一定范围内,是储存在常量池中,使用常量池中数据的对象地址是一样的,可以用 == 判断,而无需 equals()方法。

Integer a = 1;
Integer b = 1;
System.out.println(a == b);//true

Integer i = 128;
Integer j = 128;
System.out.println(i == j);//false

Integer m = new Integer(1);//新new的在堆中
Integer n = 1;//这个用的是缓冲的常量对象,在方法区
System.out.println(m == n);//false

Integer x = new Integer(1);//新new的在堆中
Integer y = new Integer(1);//另一个新new的在堆中
System.out.println(x == y);//false

 1.11.3:内部类

 概念:将一个类A定义在另一个类B里面,里面的那个类A就称为内部类,B则称为外部类

分类:

成员内部类:内部类定义在外部类的类体里,并且在外部类方法外面的类。 

普通成员内部类(非静态成员内部类):
1.普通成员内部类只能声明普通成员
2.普通成员内部类可以访问外部类的所有成员

重要:普通成员内部类,在外部类类体外创建对象,需要先创建外部类对象,再由外部类对象创建内部类对象

    Outer outer = new Outer();
    Outer.Inner inner = outer.new Inner();//非常容易记错

    Outer.Inner inner1 = new Outer().new Inner();//另一种方式,外部类没名

静态成员内部类:static 修饰的类
1.静态成员内部类可以声明静态成员和普通成员
2.静态成员内部类不能访问外部非静态成员

重要:静态成员内部类,在外部类外创建对象时,可以直接创建内部类对象,无需先创建外部类对象

    Outer.Inner2 inner2 = new Outer.Inner2();

局部内部类:内部类定义在外部类方法体里的类 

 有名的局部内部类:

1.不能有权限修饰符

2.局部内部类不能声明非静态成员,更像普通成员内部类,并且局部内部类只能在定义这个类的方法体里使用(随着方法的调用而创建,随着方法的结束而回收)

 特殊的局部内部类------匿名内部类:匿名内部类是一种特殊的局部内部类,只不过没有名称而已。所有局部内部类的限制都适用于匿名内部类。

//一个类声明在另一个类的类体里面,就叫做内部类(在定义时各种类和方法名尽量不能重名,防止给自己造成不必要的麻烦)
public class Outer {
    private int three;
    private static int four;
    //普通成员内部类
    public class Inner {
        //普通成员内部类只能声明普通成员
        //普通成员内部类可以访问外部类的所有成员
        private int five;
        //private static int six;  错误

        public void methodThree(){

        }

/*        public static void methodFour(){    错误

        }*/

    }
    //静态成员内部类
    public static class Inner2 {
        //静态成员内部类可以声明静态成员和普通成员
        //静态成员内部类不能访问外部非静态成员
        private int one;
        private static int two;

        public void methodThree(){
            System.out.println(one);
            System.out.println(two);
            //发现不能访问外部类的非静态成员(虽然是普通方法,但是身处于静态内部类里)
            // System.out.println(three);
            System.out.println(four);
        }

        public static void methodFour(){
            //不能访问内部类的非静态成员(静态方法)
            // System.out.println(one);
            System.out.println(two);
            //同样不能访问外部类非静态成员
           // System.out.println(three);
            System.out.println(four);
        }

    }

    public void methodOne() {
        //在外部类类体里创建静态和普通内部类对象(普通方法)
        Inner2 inner2 = new Inner2();
        Inner inner = new Inner();

        //局部内部类,没有修饰符,它不是一个成员
        class Inner {
            //局部内部类不能声明非静态成员,更像普通成员内部类,并且局部内部类只能在定义这个类的方法体里使用
            //private static int one;
            private int five;
            public void methodThree(){

            }
/*            public static void methodFour(){

            }*/
        }
    }

    public static void methodTwo() {
        //在外部类类体里创建静态内部类对象(静态方法)
        Inner2 inner2 = new Inner2();
    }
}
        //匿名内部类有名对象
        MyInterOne myInterOne2 = new MyInterOne(){
            @Override
            public void methodOne() {
                System.out.println("再见");
            }
        };// 注意分号
        myInterOne2.methodOne();

        //匿名内部类匿名对象
        new MyInterOne(){
            @Override
            public void methodOne() {
                System.out.println("拜拜");
            }
        };
        //匿名内部类调方法在分号前 .方法名
        //匿名内部类的匿名传参
        test(new MyInterOne(){
            @Override
            public void methodOne() {
                System.out.println("幸会");
            }
        });
    }

    public static void test (MyInterOne myInterOne){
        myInterOne.methodOne();
    }

 1.11.4:注解

 三个最基本的注解:@Override   @Deprecated     @SuppressWarnings

public class Test {
    public static void main(String[] args) {
        Person person = new Person();
        person.sayHello();

        //基本注解:抑制编译警告
        @SuppressWarnings("unused")
        int a = 100;
    }

    //基本注解:用于检测被修饰的方法为有效的重写方法,只能标记在方法上
    @Override
    public String toString() {
        return "Test";
    }
}

 class Person {

    //基本注解:标注方法已过期(过时),能用,但是不推荐
    @Deprecated
    public void sayHello(){
        System.out.println("Hello");
    }
}

Junit:回归测试框架 ,为程序员提供白盒测试,提供更多的注解。

Test注解:可以运行无参,返回类型是void的方法,选中某个方法运行,或者选择类运行其中所有    Test标注的方法
After注解:在运行Test标注的方法后运行After标注的方法
Before注解:在运行Test标注的方法前先运行Before标注的方法
AfterClass注解:类结束时运行一次
BeforeClass注解:类加载时运行一次
public class Test2 {

    //BeforeClass注解:类加载时运行一次
    @BeforeClass
    public static void staticBefore(){
        System.out.println("staticBefore");
    }

    //Before注解:在运行Test标注的方法前先运行Before标注的方法
    @Before
    public void before(){
        System.out.println("before");
    }

    //After注解:在运行Test标注的方法后运行After标注的方法
    @After
    public void after(){
        System.out.println("after");
    }

    //Test注解:可以运行无参,返回类型是void的方法,选中某个方法运行,或者选择类运行其中所有Test标注的方法
    @Test
    public void test(){
        System.out.println("test");
    }

    @Test
    public void test2(){
        System.out.println("test2");
    }

    //AfterClass注解:类结束时运行一次
    @AfterClass
    public static void staticAfter(){
        System.out.println("staticAfter");
    }
}

元注解: JDK1.5在java.lang.annotation包定义了4个标准的meta-annotation类型,它们被用来提供对其它 annotation类型作说明。

 

  • 28
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

oooosuperstar

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值