0724java基础day10static、Arrays、Math、接口、多态

static关键字

static关键字可以用来修饰成员变量和成员方法,被修饰的成员是属于类的,而不是属于某个对象,也就是说他的调用可以不依赖对象去调用(不想创建对象就用static)

类变量

当Static修饰成员变量时,该变量就是类变量,该类的每一个对象都共享同一个类变量的值,任何对象都可以更改该类变量的值,但是也可以在不创建对象的情况下对类变量进行操作。
格式:

static 数据类型 变量名

应用:static修饰的变量具有记忆功能

静态方法

static关键字可以用来修饰成员方法,我们叫类方法,习惯叫静态方法
格式:

修饰符 static 返回值类型 方法名(参数列表){
}
  • 静态方法可以直接访问类变量和静态方法
  • 静态方法不能直接访问普通方法跟普通成员变量,反之,成员方法可以直接访问类变量和静态方法
  • 静态方法中不能使用this关键字

静态方法只能访问静态成员

调用格式

建议:被static修饰的成员建议通过类名直接访问。

类名. 类变量
类名 .静态方法

演示

 //访问类变量
        System.out.println(Student.numberOfStudent);
        //调用静态方法
        Student.showNum();

静态代码块,定义在成员位置,使用static修饰代码块{}

  • 位置:类中方法外
  • 执行:随之类的加载而执行且执行一次,优先于main方法和构造执行
public class Game {
    public static int number;
    public static ArrayList<String> list;
    //作用、给类变量进行初始化赋值
    static {
        number=2;
        list = new ArrayList<String>();
        list.add("张三");
        list.add("李四");
    }
}

总结:static关键字可以修饰变量、方法、代码块。使用其主要目的还是我们不想创建对象的情况下去调用方法

Arrays类

import java.util.Arrays;其包含的所有方法均为静态方法,调用起来非常简单
-Arrays to String()返回数组内容的字符串表示形式
-Arrays.sort(arr);对指定int型数组进行升序排序

public class Demo3 {
    public static void main(String[] args) {
        int [] arr=new int[10];
        for (int i = 0; i < 10; i++) {
            arr[i]=new Random().nextInt(100);
        }
        System.out.println(Arrays.toString(arr));
        Arrays.sort(arr);
        System.out.println(Arrays.toString(arr));
    }
}

Math类

Math类包含常用的基本数学运算方法,其包含的所有方法均为静态方法
方法介绍

public class Demo4 {
    public static void main(String[] args) {
//        double d1=Math.abs(-5);//获取绝对值
//        System.out.println(d1);
//        double d2=Math.ceil(3.3);//返回大于等于参数的最小整数
//        System.out.println(d2);
//        double d3=Math.floor(-3.3);//返回小于等于参数的最小整数
//        System.out.println(d3);
//        double d4=Math.round(5.5);//四舍五入
//        System.out.println(d4);
        //计算-10.8到5.9之间,绝对值大于6小于2.1的整数有多少个
        double min=-10.8;
        double max=5.9;
        int count=0;
        for (double i = Math.ceil(min); i <= Math.floor(max); i++) {
            if(Math.abs(i)>6||Math.abs(i)<2.1){
                count++;
                System.out.println(i);
            }
        }
        System.out.println(count);
    }
}

多态

多态是继承封装之后面向对象的第三大特性
同一种行为(方法)具有不同表现形式
前提:

  • 1、继承或者实现【二选一】
  • 2、方法的重写【意义的体现,不重写无意义】
  • 3、父类引用指向子类对象【格式的体现】

体现

体现的格式

父类类型 变量名=new子类对象;
变量名.方法名

父类类型:指子类对象继承的父类类型,或者事项的父接口类型

Fu f=new Zi();
f.method();

当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误,如果有,执行的是子类重写后的方法

演示:

public abstract class Animal {
    public abstract void eat();
}

public class Cat extends Animal{

    @Override
    public void eat() {
        System.out.println("猫吃猫粮");
    }
}
public class Dog extends Animal{

    @Override
    public void eat() {
        System.out.println("狗吃骨头");
    }
}

public class TestDy {


    public static void main(String[] args) {
        Animal a1=new Cat();
        a1.eat();
        Animal a2=new Dog();
        a2.eat();
    }
}

多态的好处

在实际开发中,父类类型作为方法的形式参数,传递子类对象给方法,进行方法的调用,更能体现出多态的扩展性与遍历性。

public abstract class Animal {
    public abstract void eat();
}
public class Cat extends Animal{

    @Override
    public void eat() {
        System.out.println("猫吃猫粮");
    }
}
public class Dog extends Animal{

    @Override
    public void eat() {
        System.out.println("狗吃骨头");
    }
}
public class TestDy {


    public static void main(String[] args) {
//        Animal a1=new Cat();
//        a1.eat();
//        Animal a2=new Dog();
//        a2.eat();
        Cat c = new Cat();
        Dog d = new Dog();
        showCatEat(c);
        showDogEat(d);
        //以上两个方法均可以被showAnimalEat(Animal animal);替代,
        // 执行效果一致
        //在实际开发中,父类类型作为方法的形式参数,传递子类对象给方法,
        // 进行方法的调用,更能体现出多态的扩展性与遍历性
        showAnimalEat(c);

    }
    public static void showCatEat(Cat cat ){
        cat.eat();
    }
    public static void showDogEat(Dog dog ){
        dog.eat();
    }
    public static void showAnimalEat(Animal animal){
        animal.eat();
    }
}

由于多态特性的支持,showAnimalEat方法的Animal 类型是Cat和Dog的父类类型,父类类型接收子类对象,当然可以吧Cat对象和Dog对象传递给方法。当eat方法执行时,多态规定,执行的子类重写的方法,那么
效果与showCatEat和showDogEat方法一致。
不仅仅是替代了showCatEat和showDogEat,在扩展性方面,无论之后再多的子类出现我们都不需要编写showxxxEat方法了,直接使用showAnimalEat都可以完成,所以,多态的好处使程序编写简单,并有良好的扩展性

引用类型的转换

向上转型:当父类引用指向子类对象时就是向上转型

父类类型 变量名=new子类对象;

向下转型:父类类型向子类类型向下转化的过程,强制的

子类类型 变量名=(子类类型) 父类变量名

为什么转型

当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误,也就是说,不能调用子类拥有,而父类没有的方法,编译都错误,跟别说运行了啊,所以,想要调用子类特有的方法,必须得向下转型

public class TestDy {
    public static void main(String[] args) {
//        // 使用多态方式
//       Animal a1 =  new Cat();
//       // 执行的是子类重写后方法
//       a1.eat();
//       Animal a2 = new Dog();
//       a2.eat();
//        Cat c =  new Cat();
//        Dog d =  new Dog();
//        showCatEat(c);
//        showDogEat(d);
//        // 以上两个方法,均可以被showAnimalEat(Animal animal)方法替代
//        // 执行效果一致
//        // 实际的开发过程中, 父类类型作为方法的形式参数, 传递子类对象给方法,
//        //  进行方法的调用,更能体现出多态的扩展性与遍历性。
//        showAnimalEat(c);
//        showAnimalEat(d);
//        List<String> list = new ArrayList<>();
        Animal a = new Cat(); // 向上转型
        a.eat();
////        Cat c = (Cat)a;  // 向下转型
////        c.catchMouse();
//        Dog d = (Dog)a;  // 向下转型
//        d.watchHouse(); // ClassCastException
        // 为了避免转型发生异常,最好先做个判断
//        变量名 instanceof 数据类型
        // 向下转型
        if(a instanceof Cat){
            Cat c = (Cat)a;
            c.catchMouse();
        }else if (a instanceof Dog){
            Dog d = (Dog)a;
            d.watchHouse();
        }
    }
    public static void showCatEat(Cat cat){
        cat.eat();
    }
    public static void showDogEat(Dog dog){
        dog.eat();
    }
    public static void showAnimalEat(Animal animal){
        animal.eat();
    }
}

接口(interface)

是java中一种引用类型,是方法集合,如果类的内部封装了成员变量,构造方法和成员方法,那么接口的内部主要就是封装了方法

  • 包含了抽象方法(JDK7以前只有抽象方法)
  • 默认方法和静态方法(JDK8)
  • 私有方法(JDK9)
    接口也会被变异成.class文件,但是接口不是类,而是另外的引用数据类型,使用接口,不能创建对象,但是可以被实现(implements),一个实现接口的类,同样需要实现接口的所有抽象方法,否则他必须是一个抽象类

接口的定义格式

public interface 接口名{
抽象方法
默认方法
静态方法
私有方法
}

含有抽象方法

public interface InterFaceDemo {
    public abstract void method();
}

可以省略abstract

public interface InterfaceDemo {
    public void methed();
}

含有默认方法和静态方法

  • 默认方法:使用default修饰,不可以省略,供子类调用或者重写的
  • 静态方法:使用static修饰,供接口直接调用
   public default void method(){
        //执行语句
    }
    public static void method2(){
        //执行语句
    }

含有私有方法和私有静态方法

供接口中的默认方法或静态方法调用

public interface InterfaceDemo {

    private void method(){
        //执行语句
    }

}

基本实现

类与接口的关系为实现关系,即类实现接口,该类叫做实现类,也称为接口的子类
非抽象子类实现接口
1,必须重写接口中所有抽象方法
2.继承了接口的默认方法,可以直接调用,也可以重写

class 类名implements接口名{
//重写接口中所有抽象方法
//重写接口中的默认方法
}

定义接口

public interface LiveAble {
    //定义抽象方法
    public abstract void eat();
    public abstract void sleep();

}

定义实现类

public class Animal implements LiveAble{


    @Override
    public void eat() {
        System.out.println("就知道吃");
    }

    @Override
    public void sleep() {
        System.out.println("就知道睡");
    }

}

定义测试类

public class TestInterface {
    public static void main(String[] args) {
        Animal a = new Animal();
        a.eat();
        a.sleep();
    }
}

默认方法

 public default void fly(){//默认方法
        System.out.println("飞飞飞");
    }

重写默认方法

@Override
    public void fly() {
        System.out.println("飞呀飞");
    }

测试

public class TestInterface {
    public static void main(String[] args) {
        Animal a = new Animal();
        a.eat();
        a.sleep();
        a.fly(); // 调用默认方法
    }
}

image.png

静态方法

public static void run(){//静态方法
        System.out.println("嗷嗷跑");
    }
public class Animal implements LiveAble {
    // 无法重写静态方法
}

测试

public class TestInterface {
    public static void main(String[] args) {
       
        LiveAble.run();
    }
}

私有方法

  • 私有方法:只有默认方法能调用私有此方法
  • 私有静态:默认方法和静态方法可以调用
    存在的意义:当接口中存在多个默认方法并且方法中有重复的内容,可以抽取成一个私有方法供默认方法调用
 public default void fly(){
        System.out.println("飞飞飞");
        func1();
        func2();
    }

    private void func1(){
        System.out.println("func1");
    }
    private void func2(){
        System.out.println("func2");
    }

接口的多实现

一个类只能继承一个类,但是一个类可以实现多个接口

一个类可以继承一个父类,同时实现多个接口

image.png
class 类名[extends类名]implements接口1,接口2...{
}

抽象方法

接口中有多个抽象方法,实现类必须重写所有抽象方法,如果有重名,则只需写一次。

默认方法

接口中有多个默认方法时,实现类都可以继承使用如果默认方法有重名
必须重写一次

静态方法

接口中有多个静态方法时,并不会冲突,因为使用接口名调用

优先级问题

当一个类既继承了一个父类又实现了多个接口,父类中的成员方法与接口中的默认方法重名,子类就近选择执行父类的成员方法

接口的多继承

一个接口可以继承多个接口,使用extends,如果有重名的那么子接口只需要重写一次即可

总结:
  • 接口中,无法定义成员变量,但是可以定义常量,默认使用public,static,final
  • 接口中,没有构造方法,不能创建对象,
  • 接口中,没有静态代码块,因为没有成员变量(静态代码块用于成员变量的初始化)
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。