Java-抽象、接口、内部类、枚举

目录

1 抽象

1.1抽象类的细节

1.2抽象模板设计模式

2 接口

2.1接口

2.2接口的细节

2.3接口的多态

2.4接口类型的数组

2.5接口的多态传递

2.6接口VS继承

3 内部类

3.1概念

3.2内部类的分类

3.3局部内部类

3.4匿名内部类

3.5成员内部类

3.6静态内部类

4 枚举

4.1自定义枚举

4.2使用关键字enum实现枚举类

4.3Enum的成员方法

增强for循环:


1 抽象


abstract class 类名{
            //方法(实现的,抽象方法)
                        //属性
             }


1.1抽象类的细节


1).抽象类不能被实例化
2).可以有不是抽象的方法
3).一旦包含了abstract方法,则这个类必须声明为abstract
4).只能修饰类和方法
5).抽象方法不能有主体({})
6.一个类继承了抽象类必须实现抽象类的所有方法
7.不能和private、final、static一起用

1.2抽象模板设计模式


多个类实现同一个功能,设置一个抽象父类,将方法的代码提为一个方法A,不同的代码部分用抽象方法B表示,把该抽象方法B插入A方法,子类在继承该抽象类时,只用重写B方法即可,动态绑定机制,调用方法A就可以
//eg:设计一个抽象类Template:
//1).编写方法calculateTime(),可以计算某段代码的耗时
//2).编写抽象方法code
//3).编写一个子类Sub,继承抽象类Template,并实现code方法
abstract class ChouMoBan{
    public abstract void code();//抽象方法
    public void calTime(){
        long start=System.currentTimeMillis();
        code();
        long end= System.currentTimeMillis();
        System.out.println("耗时:"+(end-start));
    }
}


2 接口


2.1接口

给出一些没有实现的方法,封装到一起,到某个类要使用的时候,再根据具体的情况把这些方法写出来
interface 接口名{//属性
                //方法(抽象、static、default)
                   }
class 类名 extends 类名 implements 接口,接口{
               //自己的属性;
               //自己方法;
               //必须实现的接口的抽象方法
                   }
JDK8.0后,接口类中可以有抽象、静态方法、默认方法,接口可以有方法的具体实现(抽象[可以不写abstract]、static、default)


2.2接口的细节


1).接口不能被实例化
2).接口中的所有方法都是public方法,接口中的抽象方法可以不用abstract修饰
3).一个普通类实现接口,必须实现接口的所有方法
4).抽象类实现接口可以不用实现接口的方法
5).一个类可以同时实现多个接口
6).接口中的属性只能是public static final
7).接口中属性的访问形式:接口名.属性名
8).一个接口不能继承其他的类,但是可以继承多个别的接口,接口和接口的关系是继承,类与接口的关系是实现
9).接口的修饰符只能是public和默认,和类的修饰符一样


2.3接口的多态

形参是接口类型,可以接受实现接口的类的对象实例;接口类型的变量,可以指向实现了该接口的类的对象实例(类比对象的多态)
eg:

IF if=new Car();
interface IF{}
class Car implements IF{}


2.4接口类型的数组

类比继承的多态数组


2.5接口的多态传递

interface IH{}
interface IG extends IH{}
class Teacher implements IG{}
IH ih=new Teacher();


2.6接口VS继承


1).继承是当子类继承父类,自动拥有父类的功能,如果子类要扩展功能,通过实现接口的方式扩展
2).实现接口是对Java单继承机制的一种补充
3).接口一定程度上实现代码解耦[即:接口规范性+动态绑定]

3 内部类


3.1概念

一个类的内部又完整的嵌套了另一个类结构。被嵌套的类叫做内部类,外层的叫外部类,类的第五大成员【构造器,属性,方法,代码块,内部类】。可以直接访问私有属性,并且可以体现类与类之间的包含关系。
基本语法:
 

class Outer{//外部类
      class Inner{//内部类
      }
}
class Other{//外部其他类
}


3.2内部类的分类

定义在外部类局部位置上(方法体中):1.局部内部类(有类名)2.匿名内部类(没有类名)定义在外部类的成员位置上:1.成员内部类(没有static修饰)2.静态内部类(使用static修饰)


3.3局部内部类

定义在外部类的局部位置,通常在方法代码块中,本质任然是一个类
基本语法:
public void print(){
class 类名{
        类体}
          }
1).可以直接访问外部类的所有成员,包括私有的
2).不能添加访问修饰符,因为它的地位就是一个局部变量,不可以使用修饰符,但是可以使用final,因为局部变量也可以使用final,局部内部类可以被局部内部类继承
3).作用域:仅仅在定义它的方法或代码块中
4).外部类可以在方法中new内部类的对象,然后调用即可,因为局部内部类的作用域只是局部的,无法在方法外创建
5).如果外部类和局部内部类的成员重名时,在局部内部类中使用默认遵循就近原则,如果想访问外部类的成员,可以使用(外部类名.this.成员)去访问

3.4匿名内部类

定义在外部类的局部位置,比如方法中,并且没有类名,本质是类,内部类,该类没有名字,同时还是一个对象,new 接口一般为了简化开发,只用一次的,底层是implenments extends;new 类若写了方法会覆盖原来的方法,底层是extends
基本语法: new 类或接口(参数列表){
                        类体};
eg.

Ia ia=new Ia() {//编译类型是接口Ia,运行类型是匿名内部类(底层会分配一个类名一般含$,getClass()可以查看到运行类型)
   @Override
   public void print() {
    //实现方法体;
     }
 };
interface Ia{
    public void print();
}


1).两种调用匿名内部类的方法:ia.方法名();new Ia(){
                                            }.方法名();
2).作用域:仅仅在定义它的方法或代码块中,相当于局部变量
3).可以直接访问外部类的所有成员,包括私有的
4).如果外部类和局部内部类的成员重名时,在局部内部类中使用默认遵循就近原则,如果想访问外部类的成员,可以使用(外部类名.this.成员)去访问
5).可以当作实参直接传递,简洁高效

3.5成员内部类

定义在外部类的成员位置,并且没有static修饰
1).可以直接访问外部类的所有成员,包含私有的
2).可以添加任意访问修饰符(public,protected,默认,private)
3).作用域相当于普通成员
4).使用成员内部类,在外部类中添加方法,new成员内部类;
Innerclass02.Inner inner=new Innerclass02().new Inner();
Innerclass02.Inner inner01=new Innerclass02().getInner();
外部类类名.内部类类名  对象名=new 外部类类名.内部类类名 /方法名();
5).如果外部类和局部内部类的成员重名时,在局部内部类中使用默认遵循就近原则,如果想访问外部类的成员,可以使用(外部类名.this.成员)去访问


3.6静态内部类

定义在外部类的成员位置,有static修饰
1).可以直接访问外部类的所有静态成员,包含私有的静态,不可以访问非静态的
2).可以添加任意访问修饰符(public,protected,默认,private)
3).作用域相当于普通成员,整个类体
4).使用成员内部类,在外部类中添加方法,new成员内部类;
或者:外部类类名.内部类类名  对象名=new 外部类类名.内部类类名 /方法名();
5).如果外部类和局部内部类的成员重名时,在局部内部类中使用默认遵循就近原则,如果想访问外部类的成员,可以使用(外部类名.成员)去访问

4 枚举

枚举:一种特殊的类,里面只包含一组有限的特定的对象,不可以继承其他类,因为已经隐式继承了Enum,可以implements


4.1自定义枚举


1).将构造器私有化,防止直接new,可以get,不要setXXX方法,防止被修改
2).在内部new,对枚举对象/属性使用final+static共同修饰,实现底层的优化
3).枚举对象名通常使用全部大写,常量的命名规范
4).根据需要,定义属性

4.2使用关键字enum实现枚举类


1).使用enum代替class
2).不用new,直接使用常量名(实参列表)
3).如果有多个常量对象,使用,间隔即可
4).如果有enum来使用枚举,将定义常量对象写在最前面
5).默认继承了java.lang.enum,底层还是枚举对象

enum Season2{//关键字实现枚举,将定义常量对象放在最前面用,间隔
    SPRING ("春天","温暖"),SUMMER("夏天","炎热"),WHAT();
    private String name;
    private String desc;
//    public static  Season SPRING = new Season("春天","温暖");
//    public static  Season SUMMER= new Season("夏天","炎热");

    Season2() {
    }

    private Season2(String name, String desc) {
        this.name = name;
        this.desc = desc;
    }
    public String getName() {
        return name;
    }
    public String getDesc() {
        return desc;
    }
}

4.3Enum的成员方法


1).name():输出枚举对象的名字
2).ordinal():输出枚举对象的次序/编号,从0开始编号的
3).values():返回一个Enum类型的数组,包含所有的枚举对象
4).valueOf(“字符串”):将字符串转换成枚举对象,要求字符串为已有的对象,找到了就返回该枚举对象
5).compareTo(枚举对象):将两个枚举对象相比较,比较的是编号,返回两个编号的差

增强for循环:

for(数组类型 变量名:数组名){}:依次取出数组中的一个给变量,数组中取完了则退出循环

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值