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

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 修饰
  • 接口中, 没有构造方法,不能创建对象
  • 接口中, 没有静态代码块
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,445评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,889评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,047评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,760评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,745评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,638评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,011评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,669评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,923评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,655评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,740评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,406评论 4 320
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,995评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,961评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,023评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,483评论 2 342