面向对象3

抽象类:

​ 随着继承层次中一个个新子类的定义,类变得越来越具体,而父类变得更加一般,更加通用,类的设计应该保证父类和子类能够共享特征,有时将一个父类设计的非常抽象,以至于他没有具体的实例,这样的类就是抽象类。

​ abstract修饰类—抽象类

​ 该类不能实例化

​ 抽象类中也有构造器,便于子类实例化时进行调用

​ abstract修饰方法---抽象方法

​ 抽象方法只有方法的声明,没有方法体

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

​ 如果子类中不对父类的抽象方法进行重写,那么这个子类也必须定位抽象类

​ 抽象的使用注意:不能用来修饰属性、构造器、代码块。不能修饰私有方法(继承类不可以访 问)和静态方法。 不可以修饰final方法,类。

匿名类:

抽象类的匿名子类。

package com.geng;

public abstract class Graph {
    public abstract double getArea();
    public abstract double getPerimeter();
}
package com.geng;

public class MyTest {
    public static void main(String[] args){
        //graph相当于匿名子类的对象
        //此处虽然是new了一个抽象类,但其实是子类,类里面的就是子类重写的方法,但是这个子类没有名字
        Graph graph=new Graph() {
            @Override
            public double getArea() {
                return 0;
            }

            @Override
            public double getPerimeter() {
                return 0;
            }
        };



    }
}
接口的匿名实现类。
package com.geng;

public class InterfaceTest {
    public static void main(String[] args){
        Interface anInterface=new Interface() {
            @Override
            public void test01() {
                System.out.println("test01");
            }

            @Override
            public void test02() {
                System.out.println("test02");
            }
        };
        anInterface.test01();
        anInterface.test02();
    }


}
interface Interface{
    public void test01();
    public void test02();
}

接口(interface):和类是并列的结构

​ 通过接口实现类似多继承的效果。

​ jdk7之前:我们只能定义全局常量和抽象方法(全局常量public static final(书写时可以省略但是它依然在))(抽象方法 public abstract(也可以省略,并且依然在))

​ jdk8:除了定义全局常量和抽象方法还可以定义静态方法和默认方法)。

​ jdk8中接口定义的静态方法只能通过接口去调用,不能通过实现类或者实现类的对象去调用;

jdk8中通过实现类的对象可以调用接口的默认方法(default),如果实现类中重写了接口的默认方法,则调用重写后的,当然存在极其特殊的一种情况,当实现类实现了接口同时继承了一个父类,接口和父类中含有同名同参(接口的默认方法法 父类的方法(public))方法,那么默认调用的是父类的(类方法优先原则),此时如果重写的话一定是父类的方法(换句话说此时不可以重写接口的方法但是可以通过 接口名.super.方法名进行调用)。正是因为这样如果我们继承了多个接口,然后多个接口中含有同样的同参同名默认方法,此时这个实现类一定要重写这个方法,否则就会报错(接口冲突),当然如果实现类继承了一个含有同参同名方法的父类就不需要重写了

package com.geng;

public class InterfaceTest {
    public static void main(String[] args){
        C c=new C();
        c.test01();
        A.test02();
    }
}
interface A{
    public default void test01(){
        System.out.println("test01 Interface A");
    }
    public static void test02(){
        System.out.println("static Interface");
    }
}
interface D{
    public default void test01(){
        System.out.println("test01 Interface B");
    }

}

class B{
    public void test01(){
        System.out.println("test01 Class");
    }
}
class C extends B implements A,D{

}

关于默认方法:

Java 8 新增了接口的默认方法。

简单说,默认方法就是接口可以有实现方法,而且不需要实现类去实现其方法。

我们只需在方法名前面加个 default 关键字即可实现默认方法。

为什么要有这个特性?

首先,之前的接口是个双刃剑,好处是面向抽象而不是面向具体编程,缺陷是,当需要修改接口时候,需要修改全部实现该接口的类,目前的 java 8 之前的集合框架没有 foreach 方法,通常能想到的解决办法是在JDK里给相关的接口添加新的方法及实现。然而,对于已经发布的版本,是没法在给接口添加新方法的同时不影响已有的实现。所以引进的默认方法。他们的目的是为了解决接口的修改与现有的实现不兼容的问题。

接口中不可以定义构造器(所以接口不可以实例化)

接口通过被类实现(implents)方法来使用(进行实例化)

如果实现类是实现了接口的所有方法,那么这个类可以实例化。

如果该实现类没有实现接口的所有方法,那么这个类不可以实例化,应该定义成为抽象类。

接口和接口可以继承(并且可以多继承)------java之所以禁止类存在多继承,是为了保持java语法的可读性,防止多继承是代码耦合度增加,但是接口是不可以实例化的,所以不存在这个问题。

package com.geng;

public interface InterfaceTest {
    //全局常量
    public static final int temp1=1;
    int temp2=2;

    //抽象方法
    public abstract void temp003();
    //静态方法
    public static void temp001(){
        //TODO
    }
    //默认方法
    public default void temp002(){
        //TODO
    }
}

接口其实本质就是一种契约、标准、规范,包含着一种,如果你要怎么样,你就必须怎么样的思想。

接口就像电脑中的接口,实现类就像驱动程序

package com.geng;

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

    }
}
interface A{
  int x=0;
}
class B{
    int x=0;
}
class C extends B implements A{
    public void say(){
        //如果同名的属性必须要进行区分
        System.out.println(super.x);
        System.out.println(A.x);
    }
}

package com.geng;

public class InterfaceTest implements C{
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public InterfaceTest(String name) {
        this.name = name;
    }

    @Override
    public void test01() {
        //不可以这样写,因为interface中的属性是全局常量public static final类型
        //interfaceTest=new InterfaceTest("you");
        System.out.println(interfaceTest.getName());
    }

}
interface A{
    void test01();
}
interface B{
   void test01();

}

interface C extends A ,B{
    InterfaceTest interfaceTest=new InterfaceTest("geng");
}

内部类:

​ 当一个事物的内部,还有一个部分需要一个完整的结构进行描述,而这个内部完整的结构又只为外部事物提供服务,那么这个完整的结构就最好使用内部类。

成员内部类:静态内部类 非静态内部类 可以被final abstract

局部内部类:定义在方法内,代码块中,构造器中等等位置

public class InnerClass {
    static class AA{
        //静态成员内部类
    }
    class BB{
        //非静态成员内部类
    }
    {
        class CC{
            //局部内部类
        }
    }
    public InnerClass(){
        class DD{
            //局部内部类
        }
    }
    public void s(){
        class  EE{
            //局部内部类
        }
    }

}

我们关于内部类只需要关注

1、如何实例化内部类
静态成员内部类:

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

非静态成员内部类:

外部类 外部类对象=new 外部类();

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

2、如何在成员内部类中区分调用外部类的结构

使用类名

3、开发中局部内部类的使用
import java.util.Comparator;

public class InnerClass {
   public Comparable getComparable(){
       class MyComparable implements Comparable{
           @Override
           public int compareTo(Object o) {
               return 0;
           }
       }
       return new MyComparable();
   }

}
posted on 2021-09-19 00:10  gyp666  阅读(48)  评论(0)    收藏  举报