面向对象五

1.接口

        1.引用数据类型

        2.特殊的抽象类(可以定义抽象方法)

        3.接口为功能(抽象功能)的集合、

        4.class定义类,用interface定义接口

        5.接口多实现,类是单继承

        6.继承与实现非常像 子类有权使用父类(接口)的功能和属性

                子类继承父类,可以不重写方法直接使用

                实现类实现一个接口,但都为抽象功能,需要实现类自己重写,侧重点关注编写

        7.定义开发规范(不同类实习接口,方法名参数都一致,规范)

        8.实现解耦,降低耦合度(类似与USB接口,需要适配规则才能适用,不是为某一个外界设备进行设计,而是适配所有适合的设配)。

        注意:对于继承关系,耦合度是比接口高的,他是特定于为某些子类服务的,但接口不是,他是一个定义规范,使用用所有符合规则的实现。

        语法:

                jdk1.7之前:

                        公共的静态的常量:public static  final 可以省略

                         公共的抽象方法:public  abstract  可以省略

                jdk1.8之后:

                        静态方法:被static关键字修饰的方法

                                只能通过接口名使用,不能通过实现类使用

                        默认方法:被defalut关键字修饰的方法  可以有方法体                

                                只能通过实现类调用

                        接口多态:只能调用接口中存在发内容,对实现类新增内容不可见,如果实现类中存在重写方法调用重写后的方法。

        使用:

                1.接口不能实例化

                2.需要通过实现类进行实现 implements

                3.通过具体的实现类对象调用

                        具体实现类:重写所有的抽象方法+按需新增

                        抽象实现类:按需重写(改为default则可以拥有方法体)+按需新增        

                                需要具体的子类继承,重写抽象方法

                4.先继承后实现

                5.类和接口之间:只能实现接口,多实现接口

                6.接口与接口之间:只能继承不能实现,一个接口可以继承其他接口

                7.接口可以多实现,类只能单继承

对于多实现的接中存在同名同参数列表的抽象方法和静态方法,是不会影响抽象方法的实现的,,

因为他和他和编译前的引用变量的类型有关,但对于默认方法,因为连个接口都拥有默认方法,类似于子类的重写特性,不知道该调用哪个方法,需要实现类重写默认方法。

public interface IntefacePractice {
    public static void staicMethod(){
        System.out.println("我是静态1方法");
    }
    default void defaultMethod(){
        System.out.println("我是默认1方法");
    }
    //我是静态常量
    int a =10;
    void abstractMethod();
}
interface IntefacePractice2 extends IntefacePractice{
    @Override
    default  void abstractMethod(){

    }
}
interface Inteface2{
    void abstractMethod();
    public static void staicMethod(){
        System.out.println("我是静态3方法");
    }
    default void defaultMethod(){
        System.out.println("我是默认3方法");
    }
}
class TextClass implements  IntefacePractice,Inteface2{
    public static void main(String[] args) {
        IntefacePractice textClass = new TextClass();
        textClass.abstractMethod();
        IntefacePractice.staicMethod();
        textClass.defaultMethod();

    }

    @Override
    public void defaultMethod() {
        System.out.println("我是默认4方法");
    }

    @Override
    public void abstractMethod() {
        System.out.println("abstract");
    }

}

运行结果

2.内部类           

        类中定义的类

        外部类    内部类

        分类:

                成员内部类:内部类定义在成员的位置(可以继承和实现)具有成员的特点,可以被成员修饰符修饰....

                

                注意:成员内部类不能定义静态内容,除了静态常量

                        成员内部类中可以直接使用外部类的成员,包括私有。

                        外部类中可以通过成员内部类调用成员内部类属性或功能

                        通过外部类对象去创建内部类的对象,通过成员内部类对象调用成员内部类成员。

                成员内部类与外部类成员重名问题:        

                私有内部类:

                        私有内部类:被private关键字修饰的成员内部类

                                        私有内部类可以直接使用外部类的成员,包括私有的

                                        在外部类中,可以直接new  内部类对象 调用成员

                                        私有内部类只能在当前外部类中使用,在其他类中无法使用

                静态内部类:

                        被static修饰的内部类

                        静态内部类中可以定义静态内容(不能直接使用外部类成员,需要根据对象才能调用)

                        在静态内部类可以直接使用静态内容,需要通过外部类对象调用外部类成员

                         使用:

                                外部类.内部类  名 = new 外部类.内部类();

                局部内部类:

                        定义在局部位置

                        局部内部类可以定义成员内容,不可以定义静态内容,除了静态常量

                        只能在局部内部类所在的方法中通过对象访问成员

                        如果在局部内部类中使用所在方法中局部(参数),要求局部变量被fianl修饰

                        如果在jdk1.8只会版本默认被final修饰   

                        

public class InnerClass {
    static int j = 10;
    int  i = 1;
    class Inner{

        int i= 2;
        public void method(){
            int i = 3;
            //调用外部类成员变量
            System.out.println(InnerClass.this.i);
            //调用内部类成员变量
            System.out.println(this.i);
            //调用局部变量
            System.out.println(i);
        }
    }
    int b = 4;
    public void method(){
        final  int  i = 4;
        class LocalInner{
            int a = 10;
            public void method(){
                System.out.println(i);
                System.out.println(a++);
                System.out.println(b++);
                System.out.println("--------------------------------------------------");
            }
        }

        LocalInner localInner = new LocalInner();
        LocalInner localInner2 = new LocalInner();
        localInner.method();
        localInner2.method();
    }

                           运行结果:

                                

                         对于外部类的成员变量的值,影响的是所有内部类对象

                        对于调用局部外部类的方法中的局部变量必须定义为常量

                 ***匿名内部类: 

                        作用:简化实现类|子类,没有自己类本身作用的实现类|子类

                         1.匿名对象:只能在当前位置使用一次

                          2.引用指向匿名内部类对象

                         3.匿名内部类对象作为方法的实参

                         匿名内部类对象:实现类|子列+创建对象 一步搞定创建匿名内部类对象和匿名内部类类体。

                         new 接口{}接口实现类类体

                                

        //1.直接使用
        new IntefacePractice() {  //new对象+创建类体
            @Override
            public void abstractMethod() {

            }
        };
        //2.地址指向引用变量
        IntefacePractice a = new IntefacePractice() {
            @Override
            public void abstractMethod() {

            }
        };
        //3.作为实参传递
        method(new IntefacePractice() {
            @Override
            public void abstractMethod() {

            }
        });
    }

     理解:

        匿名内部类理解起来是比较抽象的,他通过直接new接口 + 实现类类体,创建一个匿名实现类对象,我们可以通过我们既然通过接口实例化对象,我们就需要对这个接口的抽象方法进行一个补全操作。   

内部类编译后的字节码文件  外部类$内部类 

3.lamba表达式

    作用:简化匿名实现类对象

  •  前提:函数式接口(这个接口只有一个必须被重写的抽象方法)
  • 强制检查是否为函数式接口:@FunctionalInterface
    • 语法:     
              1.  ()->{}

                                   () : 接口中抽象方法的参数列表

                                    -> : lambda符号|箭头函数

                                    {}:重写的方法体

                        2.如果方法体语句只有一句,前后的{}可以省略

                        3. 如果方法存在参数,参数的类型可以省略

                        4.如果参数只有一个,前面的括号可以省略

                        5.如果lambda语句只有一句,前后的{}与return关键字可以一起省

@FunctionalInterface //强制检查该接口是不是函数式接口
public interface LambdaTest {
        public void abstractMethod();
}
@FunctionalInterface //强制检查该接口是不是函数式接口
interface LambdaTest2 {
    public void abstractMethod(int a);
}
interface LambdaTest3 {
    public int abstractMethod(int a);
}
class TestLambda{
    public static void main(String[] args) {
        // 正常写法
        LambdaTest lambdaTest = ()->{
            System.out.println();
        };
        //只有一条语句时
        LambdaTest lambdaTest2 = ()-> System.out.println();
        //不需要写形参类型 会自动推断
        LambdaTest2 lambdaTest3 = (a)-> System.out.println();
        //只有一个参数时 可以不用写小括号
        LambdaTest2 lambdaTest4 = a-> System.out.println();
        //有返回值  但只有一条语句时
        LambdaTest3 lambdaTest5 = a-> a;
        
    }
}

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值