美文网首页
day10 static、Arrays、Math、接口、多态

day10 static、Arrays、Math、接口、多态

作者: __method__ | 来源:发表于2020-07-24 10:04 被阅读0次

    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("zhangsan");
            list.add("lisi");
    
        }
    }
    

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

    Arrays类

    import java.util.Arrays; 其包含的所有方法均为静态方法,调用起来非常简单

    • Arrays.toString() 返回数组内容的字符串表示形式
    • Arrays.sort(arr) 对指定的int 类型数组进行升序排序
      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 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);
    
        }
    

    多态

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

    • 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) {
            Cat c =  new Cat();
            Dog d =  new Dog();
            showCatEat(c);
            showDogEat(d);
            // 以上两个方法,均可以被showAnimalEat(Animal animal)方法替代
            // 执行效果一致
            // 实际的开发过程中, 父类类型作为方法的形式参数, 传递子类对象给方法, 
            //  进行方法的调用,更能体现出多态的扩展性与遍历性。
            showAnimalEat(c);
            showAnimalEat(d);
            
        }
    
        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方法一致。
    不仅仅是替代,在扩展性方面,无论之后再多的子类出现,我们都不需要编写showXXXeat方法了, 直接使用showAnimalEat都可以完成
    所以,多态的好处使程序编写简单,并有良好的扩展性

    引用类型转换

    向上转型

    • 向上转型:当父类引用指向子类对象时。
    父类类型  变量名  = new 子类对象;
    

    向下转型

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

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

    为什么转型

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

    public abstract  class Animal {
        public abstract void eat();
    }
    
    public class Cat extends Animal {
    
        @Override
        public void eat() {
            System.out.println("小猫吃鱼");
        }
        public void catchMouse(){
            System.out.println("抓老鼠");
        }
    }
    
    
    public class Dog extends Animal {
    
        @Override
        public void eat() {
            System.out.println("狗吃骨头");
        }
        public void watchHouse(){
            System.out.println("看家");
        }
    }
    
    
      public static void main(String[] args) {
             Animal a = new Cat(); // 向上转型
            a.eat();
    
            // 为了避免转型发生异常,最好先做个判断
            //  变量名 instanceof 数据类型
            // 向下转型
            if(a instanceof Cat){
                Cat c = (Cat)a;
                c.catchMouse();
            }else if (a instanceof Dog){
                Dog d = (Dog)a;
                d.watchHouse();
            }
    
    
        }
    

    接口(interface)

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

    • 包含抽象方法(JDK7以前)
    • 默认方法和静态方法(JDK8)
    • 私有方法(JDK9)
      接口也会被编译成.class, 但是接口不是类。
      使用接口,不能创建对象,但是可以被实现(implements), 类似继承,一个实现接口的类,同样需要实现接口的所有抽象方法,否则他必须是一个抽象类。

    定义格式

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

    含有抽象方法

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

    可以省略abstract

    public interface InterFaceDemo {
        public  void method();
    }
    

    含有默认方法和静态方法

    • 默认方法: 使用 default修饰, 不可以省略,供子类调用或者子类重写
    • 静态方法:使用 static 修饰,供接口直接调用
    public interface InterFaceDemo {
        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("飞飞飞");
        }
    

    重写默认方法

    public class Animal implements LiveAble {
    
        @Override
        public void eat() {
            System.out.println("就知道吃");
        }
    
        @Override
        public void sleep() {
            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(); // 调用默认方法
        }
    }
    

    静态方法

    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");
        }
    

    接口的多实现

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

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

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

    抽象方法

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

    默认方法

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

    静态方法

    接口中存在同名的静态方法并不会冲突, 因为使用接口名调用

    优先级

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

    接口的多继承

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

    总结
    • 接口中, 无法定义成员变量, 但是可以定义常量,其值不可该表,默认使用public static final 修饰
    • 接口中, 没有构造方法,不能创建对象
    • 接口中, 没有静态代码块

    相关文章

      网友评论

          本文标题:day10 static、Arrays、Math、接口、多态

          本文链接:https://www.haomeiwen.com/subject/euwdlktx.html