抽象类 接口及内部类

抽象类

抽象方法和抽象类的定义格式

  1. 抽象方法定义:共性的行为抽取到父类之后,由于每一个子类执行的内容是不一样的,所以在父类中不能确定具体的方法体,该方法就可以定义为抽象方法
  2. 抽象类:如果一个类中存在抽象方法,那么该类就必须声明为抽象类
  3. 抽象方法定义格式:
pubic abstract int maxValue(int[] arr);

    4. 抽象类的定义格式: 

public abstract class AddTwo{}

   5. 抽象类和抽象方法的注意事项

        抽象类不能被实例化

        抽象类中不一定有抽象方法,有抽象方法的类一定是抽象类 

        可以有构造方法:作用 创建子类对象时,给属性进行赋值

        抽象类的子类:

                要么重写抽象类中的所有抽象方法

                要么是抽象类

接口

为什么有接口?

        接口就是一种规则,对行为的抽象

如何定义一个接口?

        1. 定义:接口用关键字interface来定义

public interface add{}

        2. 接口不能实例化

        3. 接口和类之间是实现关系,通过implements关键字表示 

public class Student implements add{}

         4. 接口的子类(实现类)

        要么重写接口中的所有抽象方法

        要么是抽象类

        注意:1)接口和类的实现关系,可以是单实现,也可以是多实现

public class Student implements add,maxValue{}

                 2)实现类还可以再继承一个类的同时实现多个接口

        5. 完整代码

package interfaceTest;

public interface Swim {

    abstract void swim();
}

接口中成员的特点

  1. 成员变量

        只能是常量

        默认修饰符:public static final

    2. 构造方法

        没有

    3. 成员方法

        只能是抽象方法

        默认修饰符:public abstract

        JDK7以前:接口中只能定义抽象方法

        JDK8的新特性:接口中可以定义有方法体的方法

        JDK9的新特性:接口中可以定义私有方法

接口和类之间的关系

类和类之间的关系

        继承关系,只能单继承,不能多继承,但是可以多层继承

类和接口的关系

        实现关系,可以单实现,也可以多实现,还可以再继承一个类的同时实现多个接口

        若接口中有重名的方法,则重写一次就好

        例如:Inter1:

public interface Inter1 {
    void method1();
    void method2();
    void method3();

}

        Inter2:

public interface Inter2 {
    void method1();
    void method2();
    void method6();
}

        实现类:

package interfacedemo3;

public class InterImpl implements Inter1,Inter2{


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

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

    @Override
    public void method6() {
        System.out.println("method6");

    }

    @Override
    public void method3() {
        System.out.println("method3");

    }
}

接口和接口的关系

         继承关系,可以单继承,也可以多继承,但是如果实现类实现了子接口,则需要重写接口所有方法

例如:Inter1:

public interface Inter1 {
    void method1();
}

        Inter2:

public interface Inter2 {
    void method2();
}

        Inter3:

public interface Inter3 extends Inter1,Inter2{

    void method3();
}

        实现类: 

public class InterImpl implements Inter3{

    @Override
    public void method3() {

    }

    @Override
    public void method1() {

    }

    @Override
    public void method2() {

    }
}

JDK8开始接口中新增的方法

JDK8以后接口中新增的方法

  1.  允许接口中定义默认方法,需要使用关键字default修饰   作用:解决接口升级问题
  2. 接口中默认方法定义格式:

        格式:public default 返回值类型 方法名(参数列表){}

        范例:public default void show(){}

        

public interface Inter {

    void method();

    public default void show(){
        System.out.println("default method");
    }
}

    3. 接口中默认方法的注意事项:

        默认方法不是抽象方法,所有不强制被重写。但是如果被重写,重写的时候去掉default关键字;

        public可以省略,default不能省略;

        如果实现了多个接口,多个接口中存在相同名字的默认方法,子类就必须对该方法进行重写;

    4. 允许在接口中定义静态方法,需要用static修饰

    5. 接口中静态方法的定义格式:

        格式:public static 返回值类型 方法名(参数列表){}

        范例:public static void show(){}

        

public interface Inter {


    void method();


    static void show(){
        System.out.println("Hello World");
    }
    
}

    6. 接口中静态方法的注意事项

        静态方法只能通过接口名调用,不能通过实现类名或者对象名调用

        public可以省略,static不能省略

总结:JDK8的新特性:接口中可以定义有方法体的方法(默认,静态)

JDK9的新特性:接口中可以定义私有方法 

接口中私有方法的定义格式:

        格式1:private 返回值类型 方法名(参数列表){}

        范例1:private void show(){}

        

public interface Inter {
    
    public default void show1(){
        System.out.println("show start");
    }

    public default void show2(){
        System.out.println("show end");
    }

    private void show3(){
        System.out.println("hhh 100 code");
    }

}

        格式2:private static 返回值类型 方法名(参数列表){}

        范例2:private static void method(){}

        私有方法分两种:普通的私有方法和静态的私有方法

接口的应用

        接口代表规则,是行为的抽象。想要让哪个类拥有一个行为,就让这个类实现对应的接口就可以

        当一个方法的参数是接口时,可以传递接口所有实现类的对象,这种方式称之为接口多态

适配器设计模式

        设计模式(Design pattern):为了可重用代码,让代码更容易被他人理解,保证代码可靠性,程序的重用性

        适配器设计模式:解决接口与接口实现类之间的矛盾问题

        相当于在接口和实现类之间添加了一个类,该类空实现接口,然后让实现类继承这个类,重写里面的方法即可。

        书写步骤:

  1.  编写中间类XXXAdapter,实现对应的接口
  2.  对接口中的抽象方法进行空实现        
  3.  让真正的实现类继承中间类,并重写需要用的方法
  4. 为了避免其他类创建适配器类的对象,中间的适配器类用abstract进行修饰

内部类 

        类的五大成员:

        属性,方法,构造方法,代码块,内部类

定义

        在一个类里面,再定义一个类

为啥有内部类

        内部类表示的事物是外部类的一部分

        内部类单独出现没有任何意义

内部类的访问特点

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

        外部类要访问内部类的成员,必须创建内部类的对象

内部类的分类

        成员内部类

        静态内部类

        局部内部类

        匿名内部类:掌握

成员内部类

        定义:写在成员位置的,属于外部类的成员

        书写格式:

        

public class Car {

    private String carName;
    private String carColor;
    int carAge;


    public void show(){
        System.out.println("Car Name: " + carName);
        Engine engine = new Engine();
        engine.enginAge = 10;
        System.out.println("Car age: " + engine.enginAge);
    }


    class Engine{
        private String carEngine;
        int enginAge;

        public void show(){
            System.out.println("Car Name: " + carName);
            System.out.println("engine age: " + enginAge);
        }
    }

}

        成员内部类可以被一些修饰符所修饰,比如:private,默认(在本包中使用),protected(在其他类的子包中),public,static等 

        在成员内部类里面,JDK16之前不能定义静态变量,JDK16开始才可以定义静态变量

      获取成员内部类对象  

        方式一:

        在外部类中编写方法,对外提供内部类的对象

public class Outer {
    String name;

    class Inner {

    }

    public Inner getInner() {
        return new Inner();
    }
}
public class Test {
    public static void main(String[] args) {

        Outer o = new Outer();
        o.getInner();
    }
}

        方式二:

        直接创建格式:外部类名.内部类名 对象名 = 外部类对象.内部类对象;(适用于private修饰的成员内部类)

        

public class Outer {
    String name;

    class Inner {

    }
}
public class Test {
    public static void main(String[] args) {

        Outer.Inner oi = new Outer().new Inner();
    }
}

 当外部类成员变量和内部类成员变量重名时,在内部类如何访问?

public class Outer {
    private int x = 10;
    class Inner {
        private int x = 20;

        public void show(){
            int x = 30;
            System.out.println(x);
            System.out.println(this.x);
            System.out.println(Outer.this.x);
        }
    }
}

静态内部类 

        静态内部类指的是在内部类的前面加上static关键字,静态内部类只能访问外部类中的静态变量和静态方法,如果想要访问非静态的需要创建对象

        创建静态内部类对象的格式:外部类名.内部类名 对象名 = new 外部类名.内部类名

        调用非静态方法格式:先创建对象,用对象调用

        调用静态方法格式:外部类名.内部类名.方法名

局部内部类 

         1. 将内部类定义在方法里面就是局部内部类,类似于方法里面的局部变量

         2. 外界是无法直接使用,需要在方法内部创建对象并使用

         3. 该类可以直接访问外部类的成员,也可以访问方法内的局部变量

package linnerdemo5;

import org.w3c.dom.ls.LSOutput;

public class Outer {
    int b = 10;

    public void show(){
        int a = 20;
        class Inner{

            String name;
            int age;



            public void show1(){
                System.out.println("show1");
                System.out.println(b);
                System.out.println(a);
            }

            public static void show2(){
                System.out.println("static show2");
            }
        }
        Inner inner = new Inner();
        inner.show1();
        inner.age = 10;
        inner.name = "lazyGirl";
        inner.show2();
        Inner.show2();
    }
}

匿名内部类 

        定义:匿名内部类本质上就是隐藏了名字的内部类,可以写在成员位置,也可以写在局部位置  实现或继承 方法的重写 对象创建

        格式: new 类名或者接口名(){

                重写方法;

        };

        重写接口

public class Test {
    public static void main(String[] args) {

        new Swim(){

            @Override
            public void swim() {
                System.out.println("rewrite swim");
            }
        };
    }
}

        重写类 

        new Animal(){

            @Override
            public void eat() {
                System.out.println("rewrite eat");
            }
        };

        文件夹显示:

         

         反编译看class文件内容:

        

       

        使用场景:当方法的参数是接口或者类时,以接口为例,可以传递这个接口的实现类对象,若实现类只要使用一次,就可以用匿名内部类简化代码 

 

 

        

        

        

        

  • 29
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值