Java面向对象 继承 多态

面向对象 (继承、多态)

1、static静态

static(静态) 关键字

用于修饰成员变量和成员方法

特点:

  • 被所有的对象所共享
  • 可以使用类名调用
  • 静态加载优先于对象
  • 随着类的加载而加载

注意事项:

  • 静态方法只能访问静态成员
  • 非静态方法既可以访问静态也可以访问非静态
  • 非静态方法中不可以定义静态变量
  • 静态方法中不可以定义this,super关键字

优缺点:

  • 优点
    • 对对象的共享数据提供单独的存储空间,节省空间
    • 直接被类名调用,不用在堆内存创建对象
  • 缺点
    • 访问出现局限性(只能访问静态)
package one;

/**
 * Created by JackFeng on 2020/3/8.
 */

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

        /*
        * Math 主要的数学运算方法
        * */

//        static double abs ( double a) : 返回绝对值
        System.out.println(Math.abs(15));
        System.out.println(Math.abs(-10));
        System.out.println("----------");

        // ceil  天花板 向上取整
        System.out.println(Math.ceil(1.2));
        System.out.println(Math.ceil(1.6));
        System.out.println("----------");

        // floor 向下取整
        System.out.println(Math.floor(1.2));
        System.out.println(Math.floor(1.8));
        System.out.println("==========");


        // round 四舍五入
        System.out.println(Math.round(1.2));
        System.out.println(Math.round(1.6));
        System.out.println("---------");


        // max  min
        System.out.println(Math.max(3,8));

        // pow 次幂  第一个参数的第二个参数次幂

        System.out.println("2 的3 次方");
        System.out.println(Math.pow(2,3));

        // random 随机数  大于0 <1
        System.out.println(Math.random());


    }
}

2、代码块

写一个数据操作的工具类,取最大值,已经取数组中指定索引的值

MyArray 工具类

package com.a2data;

/**
 * Created by JackFeng on 2020/3/13.
 */
public class MyArrays {
    // 数组操作 有关的工具类 ,不需要创建对象,所以 可以私有他的构造方法

    private MyArrays(){}


    // 取最大值

    public static  int getMax(int[] arr){

        // 定义参照物
        int max = arr[0];
        for (int i = 1; i <arr.length ; i++) {

            if (max<arr[i]){
                // 替换参照物
                max = arr[i];
            }
        }
        return max;
    }

    // 获取指定数组中指定元素的索引位置

    public static int getIndex(int[] arr,int a){

        for (int i = 0; i <arr.length ; i++) {
            if (arr[i]== a)
                return i;
        }
        return -1;
    }


}


MyArrayDemo 工具类使用

package com.a2data;

/**
 * Created by JackFeng on 2020/3/13.
 */
public class MyArrayDemo {
    public static void main(String[] args) {
        int[] arr = {1, 2, 3, 4, 5, 21};

        int max = MyArrays.getMax(arr);

        System.out.println(max);

        int index = MyArrays.getIndex(arr, 3);
        int index1 = MyArrays.getIndex(arr, 6);
        System.out.println(index);
        System.out.println(index1);
    }
}

局部代码块:

​ 存在于方法中,控制变量的生命周期(作用域)

构造代码块:

​ 去构造方法中的共性,每次创建对象都会执行,并且在构造方法执行之前执行。

静态代码块:

​ 随着类的加载而加载,只加载一次,加载类时需要加载的驱动

3、继承

继承:Extends

​ 多个类有共同的成员变量和成员方法,抽取到另外一个类中(父类)

只能继承一个父类。 — 只有一个亲爹

只能继承父类非私有成员

支持多层继承 — 还可以有一个亲爷爷

superthis相似,获取父类的成员和方法。 就近原则!

方法重写:

​ 在子父类当中,子类的方法和父类的方法完全一样,子类重写了父类的方法(覆盖)。并且super 调用父类的方法即可。

注意事项:

  • 不能重写父类私有的方法
  • 必须大于等于父类方法的权限

注解:@

  • @Override

继承中构造方法的执行顺序:

子父类继承关系

  • 创建了子类的对象,就会调用子类的构造方法
  • 子类构造方法第一行没有调用父类构造方法,默认调用父类无参构造
  • 肯定先执行父类方法,因为要先给父类的成员变量进行初始化,子类可能会用到。

super() 在子类构造方法的第一行中调用父类的构造方法

继承优缺点

优点:

  • 提高代码的复用性,可维护性

缺点:

  • 耦合性的影响。

开发原则: 高内聚低耦合

  • 内聚:自己完成某件事的能力
  • 耦合:类与类的关系
package com.a2data;

/**
 * Created by JackFeng on 2020/3/13.
 */
public class ExtendsDemo {
    public static void main(String[] args) {
        Zi zi = new Zi();
        zi.function();

    }

  static class Die {
      int num = 11;

      Die(){
          System.out.println("我是父类无参构造");
      }
      public Die(int num){
          System.out.println("我是父类有参构造");
      }

      public void method(){
          System.out.println("我是父类的方法");
      }

  }

  static class Zi extends Die{

      int num = 2020;

      Zi(){
          this(1);  // 第一行不调用子类,或者其他方法,默认调用父类

          System.out.println("我是子类无参构造");
      }
      Zi(int num){
          System.out.println("我是子类有参构造");
      }


      public void  method(){
          System.out.println("我是子类的方法");
      }

      void function(){
//          this.method();

          this.num = 20;
      }

  }

}

this和super的区别

this和super的区别:

  • this: 当前对象的引用
    • 调用子类的成员变量
    • 调用子类的成员方法
    • 在子类的构造方法第一行调用子类其他构造方法
  • super : 子类对象的父类引用
    • 调用父类的成员变量
    • 调用父类的成员方法
    • 在子类的构造方法第一行调用父类的构造方法

4、匿名对象&final

匿名对象:没有名字的对象

场景:

​ 当方法只是使用一次的时候,可以使用匿名对象

​ 可以当做参数传递,但无法进行操作

注意:

​ 匿名对象可以调用成员对象,并赋值,但是并没有意义,因为只调用一次

package com.a2data;


/**
 * Created by JackFeng on 2020/3/13.
 */
public class AnonyDemo {
    public static void main(String[] args) {

//        Student s = new Student();
//        s.study();

        new Student(); // 匿名对象,没有变量名引用的对象

    }
}

class Student{
    String name;
    int age;

    public void study(){
        System.out.println("加油提升自己");
    }
}

Final

修饰符: 可以用于修饰类,成员方法和成员变量

final所修饰的类,不可被继承,不能有子类

final所修饰的方法,不能被重写。

final所修饰的变量,是不可修改的,是常量

常量

  • 字面值常量: 1,2,3
  • 自定义常量:被final所修饰的成员变量,一旦初始化则不可改变

注意:

  • 自定义常量必须初始化,可以选择显示初始化或者构造初始化

5、抽象类

abstract: 关键字,用于修饰方法和类

抽象方法

​ 不同类的方法是相似的,但是具体内容又不太一样,所以我们智能抽取它的申明,没有具体的方法体,没有具体方法体的方法就是抽象方法

抽象类:

​ 有抽象方法的类必须是抽象类

特点:

  • 抽象方法只能在抽象类里边
  • 抽象类和抽象方法必须被abstract修饰
  • 抽象类不能创建对象(不能实例化)
  • 抽象类中可以有非抽象的方法
  • 抽象类和类的关系也是继承

抽象类的成员特点

  • 成员变量
    • 可以有成员变量
    • 可以有常量
  • 成员方法
    • 可以有抽象方法
    • 可以有非抽象方法
  • 构造方法
    • 可以有构造方法的,需要对抽象类的成员变量进行初始化

注意:

​ 一个类继承了抽象类需要重写他所有的抽象方法,否则这个类就得是抽象类

package com.a2data;

import sun.plugin2.message.JavaReplyMessage;

/**
 * Created by JackFeng on 2020/3/15.
 */


/*
*
* 普通教练,高级教练
*
*
* 共性:
*   属性  姓名 年龄 性别
*   行为  教学
*
* */

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

        BasicTeacher bt = new BasicTeacher();
        bt.name = "小白教练";
        bt.teach();


        JobTeacher jt = new JobTeacher();
        jt.name = "小灰教练";
        jt.teach();


    }
}


abstract class  Teacher{
    String name; // 姓名
    int age; // 年龄
    String gender;

    public abstract void teach();

}

class BasicTeacher extends Teacher{

    @Override
    public void teach() {
        System.out.println(name + "讲基础内容");
    }
}


class JobTeacher extends Teacher{

    @Override
    public void teach() {
        System.out.println(name+ "讲高级实战内容");
    }
}



6、接口

interface: 接口是一个比抽象类还抽象的类,接口里所有的方法全是抽象方法,接口和类的关系是实现,implements

格式:

  • interface 接口名 {

    }

特点:

  • 只能有抽象方法
  • 只能有常量
  • 只能用 publie&abstract 方法
  • 默认使用public static final 来修饰成员变量
  • 建议 手动输入默认修饰符(public&abstract),虽然不输入也会是默认的。

注意:

  • 接口不能创建对象(不能实例化)
  • 类与接口的关系是实现关系,一个类实现一个接口必须实现它的所有方法

类与类:继承关系,单一继承,多层继承

类与接口:实现关系,多实现

接口与接口关系: 继承关系,多层继承

接口优点:

  • 1、类与接口的关系,实现关系,而且是多实现,一个类可以实现多个接口,类与类之间是继承关系,java中的继承是单一继承,一个类只能有一个父类,打破了继承的局限性
  • 2、对外提供规则(统一要求,例如Use接口,充电器接口)
  • 3、降低程序的耦合性
    • 定义规则,模块化开发
    • 高内聚低耦合,提高开发效率

接口和抽象类的区别:

  • 共性: 抽取出抽象的概念
  • 区别1:与类的关系
    • 类与接口是实现关系,多实现
    • 类与抽象类是继承关系,Java中的继承是单一继承,一个类只能有一个父类,java中的继承是多层继承
  • 区别2:成员
    • 成员变量:
      • 抽象类可以有成员变量,也可以有常量
      • 接口只能有常量
    • 成员方法:
      • 抽象类可以有抽象方法,也有非抽象方法
      • 接口只能有抽象方法,默认修饰符 public abstract
    • 构造方法:
      • 抽象类有构造方法的
      • 接口没有构造方法

接口开发的思路

分析:

​ 由下至上 不断向上抽取

实现:

​ 由上至下 先实现共性

应用:

​ 使用具体的子类

package com.a2data;

/**
 * Created by JackFeng on 2020/3/15.
 */


/*
*
* 篮球运动员和教练
* 乒乓球运动员和教练
* 篮球运动员和教练要出国访问,需要学习英语
*
*
*
* */


public class InterfaceTest {
    public static void main(String[] args) {
        //篮球运动员对象
        BasketBallPlayer bp = new BasketBallPlayer();
        bp.name = "姚明";
        bp.age = 35;
        bp.gender = "男";
        bp.sleep();
        bp.study();
        bp.speak();
        System.out.println("------------");
        //乒乓球教练对象

        PingpangCoache pp = new PingpangCoache();
        pp.name = "刘教练";
        pp.age = 40;
        pp.gender = "男";
        pp.sleep();
        pp.teach();
//        pp.speak()

    }


}


class  Person{
    String name;
    int age;
    String gender;

    public Person() {
    }

    public Person(String name, int age, String gender) {
        // 成员变量初始化
        this.name = name;
        this.age = age;
        this.gender = gender;
    }


    public void eat(){
        System.out.println("吃饭");
    }


    public void sleep(){
        System.out.println("睡觉");
    }



}

interface SpeakEnglish {

    public abstract void speak();
}


// 运动员
abstract class Player extends Person{
    //学习
    public abstract void study();

}

// 教练

abstract class Coach extends Person{
    // 教
    public abstract void teach();

}


//篮球运动员

class BasketBallPlayer extends Player implements SpeakEnglish{

    @Override
    public void study() {
        System.out.println("学扣篮");
    }

    @Override
    public void speak() {
        System.out.println("说英语");
    }
}


//乒乓球运动员

class  PingpangPlayer extends Player{

    @Override
    public void study() {
        System.out.println("学颠球");
    }
}


//篮球教练

class BasketBallCoach extends Coach implements SpeakEnglish{

    @Override
    public void teach() {
        System.out.println("教扣篮");
    }

    @Override
    public void speak() {
        System.out.println("说英语");
    }
}


//乒乓球教练
class PingpangCoache extends  Coach{

    @Override
    public void teach() {
        System.out.println("教颠球");
    }
}


7、多态

前提

多态的前提:

  • 子父类继承关系
  • 方法的重写
  • 父类引用指向子类对象

动态绑定:运行期间调用的方法,是根据具体的类型,具体的方法

优缺点:

  • 优点: 可以提高可维护性(多态前提所保证的),提高代码的可扩展性
  • 缺点: 无法直接访问子类特有的成员
package com.a2data;

/**
 * Created by JackFeng on 2020/3/15.
 */
public class PoymorphicDemo {
    public static void main(String[] args) {
//        Cat cat = new Cat();
//        cat.eat();

        // 父类引用  Animal a
        // 指向  =
        // 子类对象  new Cat()
        // 动态绑定
        Animal a = new Cat();
        a.eat();


    }


}

class Animal {
    public void eat(){
        System.out.println("c吃东西");
    }
}

class Cat extends Animal{
    public void eat(){
        System.out.println("猫吃鱼");
    }
}



特点

多态的成员特点:

  • 成员变量
    • 编译时看的是左边,运行时看的是左边
  • 成员方法
    • 编译时看的是左边,运行时看的是右边
  • 静态方法
    • 编译时看的是左边,运行时看的是左边

编译时看的都是左边,运行时成员方法看的是右边,其他(成员变量和静态方法)看的都是左边

package com.java;

import java.util.Date;

/**
 * Created by JackFeng on 2020/3/15.
 */
public class PoymorphicDemo {
    public static void main(String[] args) {

        // 成员变量
        // 在继承中没有被重写的概念,没有动态绑定的概念
        // 执行的是父类的

        Dad d = new Kid();
        System.out.println(d.num);


        // 成员方法
        // 运行看右边
        System.out.println("----------");
        d.method();

        // 静态方法
        d.function(); // 使用变量去调用静态方法,相当于用变量类型的类名去调用  所以输出父类的静态方法


    }
}


class  Dad{
    int num = 1;


    public void method(){
        System.out.println("我是父类的方法");
    }

    public static void function(){
        System.out.println("我是父类的静态方法");
    }

}

class Kid extends Dad{
    int num = 21;

    public void method(){

        System.out.println("我是子类的方法");
    }

    public static void function(){
        System.out.println("我是子类的静态方法");
    }

}

多态转型

多态中的向上转型和向下转型:

  • 引用类型之间的转换
    • 向上转型
      • 由小到大(子类型转换成父类型)
    • 向下转型
      • 由大到小
  • 基本数据类型的转换
    • 自动类型转换
      • 由小到大
      • byte short char – int — long — float – double
    • 强制类型转换
      • 由大到小
package com.java;

/**
 * Created by JackFeng on 2020/3/15.
 */
public class polymorphicDemo {
    public static void main(String[] args) {

        Animal a = new Dog(); // 向上转型
        a.eat();


        Dog d = (Dog) a; // 向下转型  本身是什么类型 转换成什么类型
        d.swim();

    }
}


class Animal{
    public void eat(){
        System.out.println("吃东西");
    }

}


class Dog extends  Animal{

    public void eat(){
        System.out.println("啃骨头");
    }

    public void swim(){
        System.out.println("狗刨");
    }

}

8、权限修饰符

特点:(package

  • 可以由多层
  • 不同包下的文件名可以重复
  • 包的声明必须在第一行代码

包使用场景

类的全名: 包名.类名

同包:

​ 相同包下的类可以直接访问,不需要做其他的操作

异包:

​ 1、使用类的全名

​ 2、使用关键字import将类导入

注意:

***** 代表的是通配符,代表导入了这个包下所有的类,并没有导入子包下的类

权限修饰符

pubilc —- 访问都是对外的

  • 当前类,相同包下不同的类,不同包下的类

default

  • 当前类,相同包下不同的类
  • 当前包下使用(与protected)区别

private

  • 仅限当前类

protected — 数据保护

  • 当前类,相同包下不同的类
  • 让子类对象使用

9、内部类

成员内部类

1、在类的成员位置,和成员变量以及成员方法所在的位置是一样的

2、在内部类当中,可以直接访问外部类的成员,包括私有成员

修饰符:

  • 可以使用权限修饰符修饰成员内部类,但是如果使用私有来修饰,则无法在其他类中访问
  • 可以使用static 修饰成员内部类,不用再创建外部类对象

匿名内部类:

  • 必须在定义匿名内部类得时候创建它得对象

  • 格式:

    • new 类/接口(){

    • 继承这个类得子类对象,可以重写父类方法

    • 实现这个类得子类对象,必须实现这个接口得所有方法

    • };

  • 原理:

    • 创建了继承这个类得子类对象或者创建了实现这个接口得子类对象

应用场景:

  • 作为参数传递
package com.java;

/**
 * Created by JackFeng on 2020/3/15.
 */
public class InnerDemo {
    public static void main(String[] args) {

        Outer.Inner i = new Outer().new Inner();
        i.function();


    }
}


class Outer{
    private int num = 10;

    public void  method(){
        Inner i = new Inner();
        i.function();

    }

    class Inner{
        public void function(){
            // 私有成员 可以i直接访问
            System.out.println(num);
        }
    }

}

评论