java学习笔记part3 day01,day02


day01

static关键字

静态成员变量

  • 可以修饰成员变量和成员方法,所属于类

  • static修饰成员变量,表示该成员变量只在内存中存储一份,可以被共享,修改

  • 访问格式:类名.静态成员变量

实例成员变量

  • 没有static修饰,存在于每个对象中,所属于对象

  • 访问格式:对象.实例成员变量

package d1_static;

public class User {
    /**
     * static修饰的变量,静态成员变量,内存中只有一份,所属于类
     */
    public static int onlineNumber = 161;

    /**
     * 实例成员变量,无static修饰,所属于对象,用对象名访问
     */
    private String name;
    private int age;


    public static void main(String[] args) {
        //1. 类名.静态成员变量,推荐方式
        System.out.println(User.onlineNumber);


        //2.对象名.实例成员变量,推荐方式
        User u = new User();
        u.name = "张三";
        u.age = 21;
        System.out.println(u.age);
        System.out.println(u.name);
        u.onlineNumber++;//使用对象名访问,不推荐
        System.out.println(u.onlineNumber);
    }
}

静态成员方法

  • static修饰,归属于类,建议用类名访问,也可以用对象访问

实例成员方法

  • 没有static修饰,只能用对象访问
package d1_static;

public class Student {
    /**
     * 实例成员变量,无static修饰,属于对象
     */
    private String name;


    /**
     * 静态成员方法,有static修饰,,属于类。可以被共享访问,类名和对象名都可以访问
     */
    public static int getMax(int age1, int age2){
        return age1 > age2 ? age1 : age2;
    }

    /**
     * 实例方法,属于对象,只能用对象访问
     */
    public void study(){
        System.out.println(name);
    }


    public static void main(String[] args) {
        //1.类名.静态方法
        System.out.println(Student.getMax(4, 6));
        System.out.println(getMax(8, 6));//同一个类中,静态方法可以不写类名

        //对象.实例方法
        Student s = new Student();
        s.name = "666";
        s.study();


        //对象.静态方法,(语法可行,不推荐)
        System.out.println(s.getMax(3, 34));

    }
}

使用场景

  • 表示对象自己的行为的,方法中需要访问实例成员的,则该方法必须申明实例方法

  • 如果该方法是以执行一个公用功能为目的,则可以申明成静态方法

注意事项

  • 静态方式只能访问静态的成员,不可以直接访问实例成员

  • 实例方法可以访问静态成员,也可以访问实例成员

  • 静态方法中不可以出现this关键字,this关键字代表当前对象

工具类

  • 类中都是一些静态的方法,每个方法都是以完成一个共用的功能为目的,这个类用来给系统开发人员使用
  • 提高代码重用性
  • 工具类里都是静态方法,直接访问类名就可调用,因此工具类无需创建对象,将工具类的构造器私有
package d2_static_util;

public class Login {
    public static void main(String[] args) {
        System.out.println(Util.createVerifyCode(5));
    }
}
package d2_static_util;

public class Check {
    public static void main(String[] args) {
        System.out.println(Util.createVerifyCode(9));
    }
} return code;
    }
}
package d2_static_util;

import java.util.Random;


public class Util {
    /**
     * 工具类无需创建对象,将构造器私有化
     */
    private Util() {
    }

    /**
     * 静态方法
     */
    public static String createVerifyCode(int n){
        //开发验证码
        //1.定义变量,保存验证码
        String code = "";
        //2.定义变量,记住全部验证码字符
        String data = "qwertyuioplkjhgfdsazxcvbnmQWERTYUIOPLKJHGFDSAZXCVBNMM1234567890";
        //3. 定义循环生成随机
        Random r= new Random();
        for (int i = 0; i < n; i++) {
            //获取随机索引对应字符,连接给code
            int index= r.nextInt(data.length());
            code += data.charAt(index);
        }
        return code;
    }
}       return code;
    }
}

练习

package d2_static_util;

public class Test2 {
    public static void main(String[] args) {
        int[] arr = {};
        int[] arr1 = null;
        int[] arr2 = {12, 23, 34};

        System.out.println(ArrayUity.toString(arr));
        System.out.println(ArrayUity.toString(arr1));
        System.out.println(ArrayUity.toString(arr2));
    }
}
package d2_static_util;

public class ArrayUity {
    /**
     * 私有构造器
     */
    private ArrayUity() {
    }

    /**
     * 工具方法静态方法
     */
    public static String  toString(int[] arr){
        //1.校验
        if(arr == null){
            return null;

        }

        //2.拼接内容,返回
        //result存储
        String result = "[";
        for (int i = 0; i < arr.length; i++) {
            result += (i == arr.length -1 ?arr[i] : arr[i] + ",");
        }
        result += "]";
        return result;
    }
}

代码块

  • 类的五大成分(成员变量,构造器,方法,代码块,内部类),定义在类中方法外

  • java类下,使用{}括起来的就是代码块

  1. 静态代码块:通过static关键字修饰,随着类的加载而加载,自动触发,只执行一次
public class StaticDemo1 {

    public static String schoolName;

    /**
     * 静态代码块,有static修饰,属于类,与类一起优先加载,自动触发执行
     * 可以用于初始化,静态资源
     */
    static {
        System.out.println("------------------------");
        schoolName = "66学校";
    }

    public static void main(String[] args) {
        //静态代码块
        System.out.println(schoolName);
    }
}
  1. 构造代码块:每次创建对象的时候,调用构造器执行,都会执行该代码块中的代码,并且在构造器执行前执行
package d3_static_code;

public class StaticDemo2 {
    public String name;

    public StaticDemo2(){
        System.out.println("无参构造器被触发执行了");
    }
    /*
      构造代码块,实例代码块,属于对象,调用构造器时先执行,没有static修饰
      初始化实例资源
     */
    {
        name = "张三"
        System.out.println("=========实例代码块========");
    }
    public static void main(String[] args) {
        StaticDemo2 s1 = new StaticDemo2();
        StaticDemo2 s2 = new StaticDemo2();
    }
}
  • 静态代码块应用案例
package d3_static_code;

import d2_static_util.ArrayUity;

import java.util.ArrayList;

public class StaticDemo3 {

    /**
    * 定义静态集合,这样静态集合只加载一个,只需要一幅牌
    * static修饰,表示只在内存中存储一份,可以被共享,修改
    */
    public static ArrayList cards = new ArrayList<>();

    /*
      在程序main方法运行前,把54牌放进去,后续直接使用
     */
    static {
        //静态代码块,随着类的加载而加载,自动触发,执行一次
        //定义数组存储点数
        String[] sizes = {"3","4","5","6","7","8","9","10","J","Q","K","A","2"};
        //定义数组存储花色
        String[] colors = {"?","?","?","?"};
        //先遍历点数
        for (int i = 0; i < sizes.length; i++) {
            //sizes[i]
            //遍历花色
            for (int j = 0; j < colors.length; j++) {
                //colors[j]
                String card = colors[j] + sizes[i];
                cards.add(card);
            }
        }
        //大小王
        cards.add("小");
        cards.add("大");
    }

    public static void main(String[] args) {
        System.out.println("新牌" + cards);
    }
}

单例设计模式

  • 设计模式,问题的最优解法,有20多种

  • 单例模式,保证系统中,应用该模式的类永远只有一个实例,一个类只能创建一个对象

饿汉单例设计模式

  • 用类获取对象的时候,对象已经提前创建好了

    1. 定义一个类,构造器私有

    2. 定义静态变量,存储一个对象

    public class SingleInstance {

    //2.饿汉单例在获取对象前,对象已经提前准备好
    //对象只能是一个,所以定义静态成员变量
    public static SingleInstance instance = new SingleInstance();

    //1. 私有构造器
    private SingleInstance() {
    }
}
 public class Test {
    public static void main(String[] args) {
        SingleInstance s1 = SingleInstance.instance;
        SingleInstance s2 = SingleInstance.instance;
        System.out.println(s1 == s2);
    }
}

懒汉单例设计模式

  • 真正需要对象时,才去创建一个对象(延迟加载对象)

    1. 构造器私有(单例)

    2. 静态变量存储对象

    3. 提供方法返回单例对象

package d4_sttatic_danli;

//懒汉单例的思想
public class SinglrInstance2 {

    //2。定义静态成员变量存储单例对象,只加载一次
    //私有化
    private static SinglrInstance2 instance2;

    //3.提供方法返回单例对象
    public static SinglrInstance2 getInstance(){
        if(instance2 == null){
            //第一次,需要创建对象
            instance2 =new SinglrInstance2();
        }
        return instance2;
    }

    //1. 构造器私有
    private SinglrInstance2(){
    }
}
package d4_sttatic_danli;

public class Test2 {
    public static void main(String[] args) {
        SinglrInstance2 sq = SinglrInstance2.getInstance();
        SinglrInstance2 sq1 = SinglrInstance2.getInstance();
        System.out.println(sq == sq1);
    }
}

继承

  • 提高代码复用性

  • java中关键字extends,使用这个关键字,可以让一个类和另一个类建立起父子关系

  • 字类继承父类后,可以直接使用父类的属性和方法,字类更强大

package d5_extends;

//作为父类
public class People {
    public void  run(){
        System.out.println("人会跑");
   }
}



package d5_extends;

// 学生类,字类
public class Student extends People {

} 



package d5_extends;

public class Test {
    public static void main(String[] args) {
        //继承
        Student s = new Student();
        s.run();
    }
}

继承设计规范

  • 字类们相同特征(共性属性,共性方法)放在父类中定义,

  • 字类独有的属性,方法,行为应该定义在字类自己里面

package d6;

public class People {    //父类
    private String name; 
    private int age;

    //方法,查看课表
    public void  qc(){
        System.out.println(name + "在查看课表");
    }


    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}




package d6;

public class Student extends People {    //继承
    //字类独有行为
    public void wi(){
        System.out.println(getName() + "写作业了");
    }
}






package d6;

public class Test {
    public static void main(String[] args) {
        //基础的设计思想
        Student s = new Student();
        s.setName("张三");//使用父类
        s.setAge(23);//使用父类
        System.out.println(s.getAge());//使用父类
        System.out.println(s.getName());//使用父类
        s.qc();//使用父类
        s.wi();//使用字类
    }
}

内存运行原理

继承的特定

  1. 字类可以继承父类的属性和行为,但是不能继承父类的构造器

  2. java是单继承模式,一个类只能继承一个直接父类

  3. java不支持多继承,但支持多层继承

  4. Java中所有类都是Object类的字类

继承09,14

继承后成员变量,成员方法的访问特点

  • 就近原则

  • 局部没有找字类,字类没有找父类,父类没有报错

  • 字类和父类出现重名成员,要使用父类的成员加super关键字

package d8;

public class Test {
    public static void main(String[] args) {
        //继承后,成员的访问特定
        //就近原则
        Dog d = new Dog();
        d.lookDoor();//调用字类
        d.run();//调用子类的
        d.showName();
    }
}

class Animal {
    public String name = "动物名";
    public void run(){
        System.out.println("动物可以跑");
    }
}

class Dog  extends Animal{
    public String name = "狗名";
    public void lookDoor(){
        System.out.println("狗看门");
    }

    public void run(){
        System.out.println("狗跑的很快");
    }

    public void showName(){
        String name = "局部名";
        System.out.println(name);
        System.out.println(this.name);//当前对象name,this代表当前对象的地址
        System.out.println(super.name);//字类和父类重名时,要使用父类的成员,加关键字super
    }
}

继承后方法重写

  • 在继承关系中,字类和父类出现了一模一样的方法声明,我们就称字类这个方法是重写的方法

  • 当字类需要父类的功能,但是父类的功能不能满足自己的需求时,字类就可以重写父类中的方法

  • 方法重写的注意事项和要求,one extend重写校验注解,加上之后,方法必须是正确重写,提高程序的可读性

    1. 重新方法的名称,形参列表必须和被重写方法的名称和参数保持一致

    2. 私有方法不能被重写

    3. 字类重写父类方法时,访问权限大于或等于父类

    4. 字类不能重写父类的静态方法,重写会报错

package dd9;

public class Test {
    public static void main(String[] args) {
        NewPhone p = new NewPhone();
        p.call();
        p.semndMag();
    }
}

//父类
class Phone{
    public void call(){
        System.out.println("打电话");
    }

    public void semndMag(){
        System.out.println("发短信");
    }
}

//字类
class NewPhone extends Phone{
    @Override  //重写校验注解,加上之后,方法必须是正确重写,提高程序的可读性
    public void call(){
        super.call();
        System.out.println("视频通话");
    }

    @Override
    public void semndMag(){
        super.semndMag();
        System.out.println("发送图片");
    }
}

继承后字类构造器的特点

  • 字类中所有的构造器都会默认访问父类中的无参构造器,再执行自己

  • 字类再初始化的时候,有可能会使用到父类中的数据,如果父类没有初始化,字类讲无法使用父类的数据

  • 字类初始化前,一定要调用父类构造器完成父类数据空间的初始化

package d10;

public class Test {
    public static void main(String[] args) {
        //继承后字类构造器特定

        Dog d = new Dog();
        System.out.println(d);

        Dog d2 = new Dog("hhh");
        System.out.println(d2);
    }
}
package d10;

public class Animal {
    public Animal(){
        System.out.println("父类无参构造器执行");
    }
}
package d10;

import jdk.swing.interop.SwingInterOpUtils;

public class Dog  extends Animal{
    public Dog(){
        System.out.println("字类无参构造器");
    }

    public Dog(String name){
        System.out.println("字类有参构造器");
    }
}

继承后,字类构造器访问父类的有参构造器

  • super调用有参数构造器的作用,初始化继承自父类的数据
  package d11;


public class Test {
    public static void main(String[] args) {
        //字类构造器访问父类有参构造器
    Teacher t = new Teacher("dilei", 55);
    System.out.println(t.getAge());
    System.out.println(t.getName());
    }
}
package d11;

public class People {
    private String name;
    private int age;

    public People(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public People() {
    }

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}
package d11;

public class Teacher extends People{
    public Teacher (String name, int age){
        //调用父类有参构造器,初始化继承自父类的数据
        super(name, age);
    }
}

this和super

  • this代表本类对象的引用

  • super,代表父类存储空间

  • this和super都要在构造器的第一行,儿二者不能在同一个构造器中

  package d12;

public class Test {
    public static void main(String[] args) {
        //理解this
        Student s1 = new Student("好家伙", "666");
        System.out.println(s1.getName());
        System.out.println(s1.getSchoolName());

        Student s2 = new Student("shabi");
        System.out.println(s2.getName());
        System.out.println(s2.getSchoolName());
    }

}
package d12;

public class Student {
    private String name;
    private String schoolName;


    public Student() {
    }

    public Student(String name){
        //借用本类兄弟构造器
        this(name, "黑马");
    }

    public Student(String name, String schoolName) {
        this.name = name;
        this.schoolName = schoolName;
    }

    public String getName() {
        return name;
    }

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

    public String getSchoolName() {
        return schoolName;
    }

    public void setSchoolName(String schoolName) {
        this.schoolName = schoolName;
    }
}

day02

  • 用来管理不同的类,类似于文件夹

  • 导包:相同包下的类可以直接使用,不同包下的类必须导包才能使用

package d1_package;
//导包
import d1_package.d1_package2.Student;
public class Test {
    public static void main(String[] args) {
        //1.同一个包下的可以直接访问
        System.out.println(User.onlineNumber);


        //2.不同包下的类,必须先导包才可以访问
        Student s =new Student();


        //3.如果这个类中使用不同包下的相同类名,默认只能导入一个类的包,另一个类的包,要使用全名访问
        d1_package.d1_packer3.Student s2 = new d1_package.d1_packer3.Student();
    }
}

权限修饰符

  • 控制修饰的成员能够被访问的范围

  • 可以修饰成员变量,方法,构造器,内部类,不同权限修饰符修饰的成员能够被访问的范围将受限制

  • 有四种作用由小到大

    1. private,只能在当前类中访问
    2. 缺省,能在同一个类,同一个包中的其他类访问
    3. protected,同一个类中,同一个包中的其他类,不同包下的字类(使用字类创建新对象)
    4. public,同一个类中,同一个包中的其他类,不同包下的字类,不同包下的无关类
  • 自定义成员满足以下要求:

    1. 成员变量一般私有
    2. 方法一般公开
    3. 如果该成员只希望本类访问,使用private
    4. 如果该成员只希望本类,同一个包下的其他类和字类访问,使用protected

final关键字

  • 最终的意思,可以修饰类,方法,变量
  • 修饰类:表明该类试最终类,不能被继承
  • 修饰方法:表示该方法试最终方法,不能被重写
  • 修饰变量:表明该变量最后一次赋值,不能被再次赋值(有且只能赋值一次)
public class Test {
    public static void main(String[] args) {
        //final语法
        //final修饰类,类不能被继承,工具类可能使用
        //final修饰方法,不能被重写
        //final修饰变量,变量有且仅能被赋值一次
    }
}

/*class Student extends People{
    @Override
    public void eat(){
        System.out.println("学生也要吃");
    }
}*/

class People{
    public final void eat(){
        System.out.println("人要吃饭");
    }
}




/*
class wolf extends Animal
final class Animal{}*/
public class Test2 {

    //final修饰的静态成员变量,常量
    public static final String schoolName = "heima";

    //实例成员变量,几乎不用
    private final String name = "3333";

    public static void main(String[] args) {
        //final修饰变量的作用
        //局部变量和成员变量,

        //局部变量
        final double score = 3.14;
//        score = 3.3;第二次赋值

//        schoolName = "dddd"第二次赋值

        nam
    }
}
  • 注意:

    1. final修饰的变量是基本类型,那么变量存储的数据值不能发生改变

    2. final修饰的变量是引用类型,那么变量可存储的地址值不能发生改变,但是地址指向的对象内容是可以发生变化的

public class Test1 {
    public static void main(String[] args) {
        //final修饰引用类型的变量,地址值不能发生改变,但是指向的内容可以改变
        final Teachers t = new Teachers("学习");
        System.out.println(t.getHobby());
        t.setHobby("66666666666");
        System.out.println(t.getHobby());
    }
}
class Teachers{
    private String hobby;

    public Teachers(String hobby) {
        this.hobby = hobby;
    }

    public String getHobby() {
        return hobby;
    }

    public void setHobby(String hobby) {
        this.hobby = hobby;
    }

常量

  • 就是使用了public static final修饰的成员变量,必须有初始化值,指向过程中值不能被改变
  • 作用和好处:可以用作系统的配置信息,方便维护,提高可读性
  • 命名规范:英文单词全部大写,多个单词下划线连接起来
public class d1 {
    public static final String  SCHOOL_NAME = "44444";
    public static void main(String[] args) {
        // 常量的使用
        System.out.println(SCHOOL_NAME);
    }
}
  • 常量的执行原理

    1. 在编译阶段会执行"宏替换",把使用常量的地方全部替换成真实的字面量

常量做信息标志和分类

  • 代码可读性好,实现软编码形式

枚举类

  • java中特殊类型

  • 做信息的标志和信息的分类

public enum Season {
    //枚举第一行,罗列枚举类的对象名称,建议全队大写
    SPRING, SUMMER, AUTUMN, WINTER;
}



javac进行编译
javap进行反编译


Compiled from "Season.java"
public final class Season extends java.lang.Enum {
  public static final Season SPRING;
  public static final Season SUMMER;
  public static final Season AUTUMN;
  public static final Season WINTER;
  public static Season[] values();
  public static Season valueOf(java.lang.String);
  static {};
}
  • 枚举的特点
    1. 枚举都是继承了枚举类型,java.lang.Enum
    2. 枚举都是最终类,不可以被继承
    3. 枚举类的构造器是私有的,枚举对外不能创建对象
    4. 枚举类的第一行默认都是罗列枚举对象的名称
    5. 枚举类,相当于多例模式

抽象类

  • 在java中abstract是抽象的意思,可以修饰类,成员方法
//抽象类和抽象方法,都有sbstract修饰
public abstract class Animal {
    //抽象方法不能写,方法体代码
    public abstract void run();
} 


//抽象方法只有方法签名,不能申明方法体
//一个类中如果定义了抽象方法,必须声明这个类成抽象类。
  • 使用场景:一般作为父类,让字类继承

  • 当父类知道字类要完成某些行为,但是每个字类该行为的实现方法不同,父类就把该行为定义成抽象方法的形式,具体实现交给字类去完成,此时这个类就可以声明成抽象类

抽象类的案例

public abstract class Card {
    private String name;
    private double money;

    //定义支付方法,抽象方法
    public abstract void pay(double money);

    public String getName() {
        return name;
    }

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

    public double getMoney() {
        return money;
    }

    public void setMoney(double money) {
        this.money = money;
    }
}
public class GoldCard extends Card{

    @Override
    public void pay(double money2) {
        System.out.println("当前消费" + money2);
        System.out.println("当前余额" + getMoney());

        double rs = money2 * 0.8;
        System.out.println(getName() + "实际支付" + rs);

        //跟新余额
        setMoney(getMoney() - rs);
    }
}
public class Test {
    public static void main(String[] args) {
        //抽象类的基本使用,做父类被继承,在重写抽象方法
        GoldCard g = new GoldCard();
        g.setMoney(10000);
        g.setName("dilei");

        g.pay(300);
        System.out.println("剩余" + g.getMoney());
    }
}

抽象类的特征,注意事项

  • 类有的成分,抽象类都有

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

  • 类继承了抽象类,必须重写完抽象类的全部抽象方法,否则这个类定义成抽象类

  • 不能用abstract修饰变量,代码块,构造器

  • 抽象类不能创建对象

  • abstract和final互斥

模板方法模式

  • 把功能定义成一个模板方法,放在抽象类中,模板方法中只定义通用且能确定的代码

  • 模板方法把不能确实的功能,定义成抽象方法让字类实现

  • 模板方法用final修饰,不能让字类重写

接口

  • interface关键字,接口也是一种规范

  • jdk8之前的接口只能写常量和抽象方法

//声明了接口
public interface InterfaceDemo {
    //成分特点,jdk8之前接口中只能有抽象方法和常量
    //常量
    //由于接口体现规范思想,规范默认公开,代码层面,public abstract final可以省略
    String SCHOOL_NAME1 = "黑马";
    public static final String SCHOOL_NAME = "黑马";
    //抽象方法
    //由于接口体现规范思想,规范默认公开,代码层面,public abstract可以省略
    void ruu();
    public abstract void run();
}

接口的基本使用

  • 接口是用来被类实现(implements)的,实际接口的类称为实现类,实现类可以理解成所谓的字类

  • implements,接口可以被类多实现,必须重写完接口的全部抽象方法

public interface SpotrMan {
    void run();//接口
    void bisai();
});
}
public interface law {
    void rule();
}
public class pingpang implements SpotrMan, law {
    private String name;

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

    @Override
    public void run() {
        System.out.println(name + "跑步");
    }

    @Override
    public void bisai() {
        System.out.println(name + "参加比赛");
    }

    @Override
    public void rule() {
        System.out.println(name + "守法");
    }
}
public class Test {
    public static void main(String[] args) {
        //接口的基本使用,被类实现
        pingpang p = new pingpang("张继科");
        p.run();
        p.bisai(); q
        p.rule();
    }
}

接口和接口的关系:多继承

  • 一个接口可以继承多个接口
  • 接口继承的作用:整合多个接口为同一个接口,便于字类实现
  public interface laww {
    void rulee();
  }
public interface People {
    void eat();
    void sleep();
}
public interface SportM extends laww,People {
    void run();
    void bisai();
}
public class BasketBallMan implements SportM{

    @Override
    public void eat() {

    }

    @Override
    public void sleep() {

    }

    @Override
    public void run() {

    }

    @Override
    public void bisai() {

    }

    @Override
    public void rulee() {

    }
}
public class Test {
    public static void main(String[] args) {
        //理解接口多继承
    }
}

jdk8开始新增方法

package d13_interface_jdk8;

public interface SportMa {
    /**
     * jdk8新增默认方法,(实例方法)
     * 必须default修饰,默认是public修饰
     * 默认方法吊用,接口不能创建对象,过继给实现类,实现类的对象吊用
     */
    default void run(){
        System.out.println("paodekaui");
        go();
    };


    /**
     *静态方法
     * 使用static修饰,默认public修饰
     * 接口的静态方法,接口名自己吊用
     */
    public static void inAdd(){
        System.out.println("学习java新增方法");
    }


    /**
     * jdk9新增方法,私有方法(实例方法)
     * 必须在接口内部访问
     */
    private void go(){
        System.out.println("开始跑");
    }
}


class PingPan implements SportMa{
}

class Test{
    public static void main(String[] args) {
        PingPan p = new PingPan();
        p.run();

        SportMa.inAdd();
    }
}

接口注意事项

  • 接口不能创建对象

  • 一个类可以实现多个接口,多个接口中有同样的静态方法不冲突(只能接口自己调用 接口.方法名)

  • 一个类继承父类,同时实现接口,父类中和接口中有同名的方法,默认使用父类的

  • 一个类实现多个接口,多个接口中存在同名的默认方法,不冲突,这个类重写该方法即可

  • 一个接口继承多个接口,如果多个接口中规范冲突则不能继承