java初学4

1、interface接口

(1)[修饰符] interface 接口名 extends 父接口1,父接口2....
       •没有构造方法,不能实例化;
       •接口只能继承接口,不能继承类
       •接口里没有普通方法,方法全是抽象的;
       •接口里的方法默认修饰符是public abstract
       •接口里的字段全是全局常量,默认修饰符是public static final;
(2)接口里的成员包括(主要是前两个):
       •全局常量
       •公共的抽象方法
       •内部类(包括内部类,内部接口,内部枚举类);
使用接口
格式 : public class SubImpl  extends Super  implements IA,IB
 
•接口的实现必须在 extends 之后;
•实现接口的方法必须是 public 类型
•接口不能创建实例,但是可以声明引用类型的变量。
       •此时,引用类型的变量必须指向到其实现类对象。
       •IStudent s = new String();//
       •IStudent s = new StudentImpl();//
2、接口和抽象类异同点
(1)相同点:
       •都位于继承的顶端,用于被其他实现或继承;
       •都不能实例化;
       •都包含抽象方法,其子类都必须覆写这些抽象方法;
(2)区别:
       •抽象类为部分方法提供实现,避免子类重复实现这些方法,提供代码重用性;接口只能包含抽象方法;
       •一个类只能继承一个直接父类(可能是抽象类),却可以实现多个接口;(接口弥补了Java的单继承)
(3)二者的选用:
       •优先选用接口,尽量少用抽象类;
       •需要定义子类的行为,又要为子类提供共性功能时才选用抽象类;
3、内部类
(1)类中有类
       •内部类:嵌套类
       •外部类:宿主类
(2)把内部类隐藏在外部类之内,不许同包的其他类访问该类;
(3)内部类可以访问外部类的私有数据,外部类不能访问内部类的实现细节,比如字段;
(4)观察编译后的字节码文件
(5)非静态内部类静态内部类,局部内部类;
(6)匿名内部类适合于仅使用一次使用的类;
A、非静态内部类
     Ø若外部类字段,内部类字段,内部类方法变量同名,则其访问方式分别是:
        •访问外部类的字段:外部类类名.this.字段
        •访问内部类字段:this.字段
        •访问内部类方法的局部变量:字段
非静态内部类例子:
打印结果:
             把局部变量添加到尾巴
             把内部类属性添加到尾巴
             把外部类属性添加到尾巴
第三个Snake.this.name也可以这样访问new Snake().name
在外部类以外访问非静态内部类
(1)外部类不能用private修饰,否则不能访问
(2)外部类以外的地方定义内部类变量
       •OuterClass.InnerClass varName ;
(3)非静态内部类对象是存放在外部类的对象里的,因此在创建非静态内部类对象之前,必须先创建其外部类的对象
       •OuterInstance.new InnerClass([参数列表]);
public class InnerDemo {
    public static void main(String[] args) {
        //Outer.Inner in = new Outer().new Inner();
        Outer.Inner in;
        Outer out = new Outer();
        in = out.new Inner();
        //in.inShow();
        //Outer out = new Outer();
        //out.outShow();
    }
}

class Outer {
    class Inner {
        public void inShow() {
            System.out.println("inShow");
        }
    }
    public void outShow(){
        //System.out.println("outShow");
        Inner in = new Inner();
        in.inShow();
    }
}
在外部类以外访问非静态内部类例子
B、静态内部类
(1)使用static修饰内部类,该内部类属于其外部类,而不属于外部类的实例;
(2)静态内部类可包括静态成员也可包括非静态成员。根据静态成员不能访问非静态成员的规定,所以静态内部类不能访问外部类实例成员,只能访问外部类的静态成员;
在外部类以外访问静态内部类
(1)因为静态内部类是外部类的类成员,因此在创建内部类对象时不需创建外部类的对象;
(2)创建内部类对象:
       •new OuterClass.InnerClass([参数列表])
       •注:静态内部类的全名应该是OuterClass.InnerClass,所以要看作是一个整体;
在外部类以外访问静态内部类例子
 
C、局部内部类
(1)局部内部类:定义在方法里的内部类;
(2)特点:不能在宿主类以外的地方使用,局部内部类也不能使用访问修饰符和static修饰;
(3)对于局部变量局部内部类只能访问方法中final修饰的局部变量,因为final修饰的变量相当于一个常量,其生命周期超出了方法运行的生命周期;
       对于全局变量,局部类是可以访问的(例如下图中的name全局变量)
  
D、匿名内部类
(1)适合只使用一次的类
       •不能是抽象类,因为系统在创建匿名内部类的时候,会立即创建匿名内部类的对象。
       •匿名内部类不能定义构造器,因为匿名内部类没有类名。 
格式:
new 父类构造器([实参列表]) 或 接口()
{
    //匿名内部类的类体部分
}
注意:匿名内部类必须继承一个父类或者实现一个接口,但最多只能一个父类或实现一个接口; 
创建匿名内部类时会立即创建一个该类的实例,这个类定义立即消失,匿名内部类不能重复使用。    
4、枚举
(1)使用enum声明,默认直接继承了java.lang.Enum类,而不是Object类;
(2)枚举类的对象是固定的,实例个数有限,枚举对象后可以跟()。
(3)枚举元素是指如下这样的定义,必须位于枚举类体中的最开始部分,枚举元素后要有分号与其他成员分隔。
enum Weekend
{
    MONDAY,
    TUESDAY
}

       而枚举元素MONDAY、TUESDAY等价于:public static final Weekend MONDAY = new Weekend();

Weekend monday1 = Weekend.MONDAY;
Weekend monday2 = Weekend.MONDAY;
System.out.println(monday1 = monday2); // true
(4)枚举类的构造方法的权限修饰符默认是private;
(5)一旦枚举对象后面加上{},那么该对象实际是枚举匿名内部类对象;
(6)所有枚举类都提供一个静态的values()方法(返回该枚举类所有对象组成的数组),便于遍历所有枚举对象;
(7)所有枚举类都提供一个静态的valueOf(String name)方法, 返回枚举类中对象名等于 name的对象。 
public enum Color{
    RED(), GREEN(){}, BLUE{};
}
Java5开始出现枚举:
<1>.私有的构造方法
<2>.每个元素分别用一个公有的静态成员变量表示,枚举类的对象是固定的,实例个数有限。
<3>.枚举的直接父类java.lang.Enum;
<4>.枚举就相当于一个类,其中也可以定义构造方法、成员变量、普通方法和抽象方法。
<5>.枚举元素必须位于枚举体中的最开始部分,枚举元素列表的后要有分号与其他成员分隔。
<6>.把枚举中的成员方法或变量等放在枚举元素的前面,编译器报告错误。
<7>.枚举只有一个成员时,就可以作为一种单例的实现方式。
<8>.枚举元素有大括号对时,此时属性是枚举类的匿名内部类对象。(查看编译后的class文件)
<9>.所有枚举类都提供一个静态的values()方法(返回该枚举类所有对象组成的数组),便于遍历所有枚举对象;
<10>.Enum常见方法:
                             String name();// 返回枚举实例名称;
                             int ordinal();// 返回枚举实例在枚举类中的索引,从0开始;
                             String toString();// 返回枚举对象的"自我描述";(看源代码)
<11>.在switch语句中使用枚举对象;
<12>.枚举类的构造方法;
<13>.枚举类覆写接口抽象方法的两种方式:
                             a.在枚举类中实现接口抽象方法;
                             b.在枚举匿名内部类对象中实现接口抽象方法;
lEnum是一个抽象类,是所有枚举类的直接父类;
lEnum常见方法:
•String name();// 返回枚举实例名称;
•int ordinal();// 返回枚举实例在枚举类中的索引,从0开始;
•String toString();// 返回枚举对象的"自我描述";(看源代码)
(1)在switch语句中使用枚举对象;
(2)在枚举类中使用toString方法;
(3)使用for-each中操作枚举对象;
(4)枚举类的构造方法;
(5)枚举类覆写接口抽象方法的两种方式;注意:匿名内部类
(6)枚举实现单例模式;
 
super.toString()表示的是先调用父类的toString的方法
枚举类的构造方法
枚举类既然是一种特殊的类,那么也应该有自己的构造方法;
普通类创建对象的时候,可以接收参数,那么枚举类呢?
enum Color {
    RED("红"),GREEN("绿"),BLUE("蓝");
    
    private String name;
    private Color(String name){
        this.name = name;
    }
    public String getName(){
        return name;
    }
    public String toString() {
        return this.name;
    }
}
枚举类实现接口
枚举类覆写接口抽象方法的两种方式:
     •在枚举类中实现接口的抽象方法;
     •在枚举匿名内部类中实现接口的抽象方法;
interface I{
    void show();
}

enum Color implements I{
    RED(){
    public void show(){
        }
    }, GREEN{
    public void show(){
        }
    }, BLUE{
    public void show(){
        }
    };
}

enum Color implements I{
    RED(), GREEN, BLUE;

    public void show() {
    }
}
枚举类的单例模式
使用枚举类来实现单例模式的好处是这样非常简洁,并且无偿地提供了序列化机制,绝对防止多次实例化,即使是在面对复杂的序列化或者反射攻击的时候。
——来自《Effective Java》(作者:Josh Bloch)
enum Singleton {
    INSTANCE;//唯一实例

    public void print(){
        System.out.println("使用enum实现单例模式");
    }
    public static Singleton getInstance(){
        return INSTANCE;
    }
}
原文地址:https://www.cnblogs.com/MrZivChu/p/startstudyjava4.html