day09_面向对象_多态_static

今日内容

1.作业
2.访问修饰符
3.static
4.多态

零、复习

私有化的单词: private

继承的关键词: extends

属性的封装

  • 将属性私有,private
  • 提供一对儿set,get

继承的特性:(自己的话说明)

  • 继承目的是减少重复代码,父类代码子类自己使用
  • A extends B
  • 关于属性: 子类可以使用父类非私有的属性
  • 关于方法: 子类可以使用父类非私有的方法,
  • 如果父类方法不适用,就要重写方法
  • 关于构造: 子类构造方法内有super()可以调用父类构造方法

this能干什么

  • this调用属性,调用方法,调用构造方法

super能干什么

  • 调用父类属性,调用父类方法,调用父类构造方法

重写的语法

  • 子类和父类的访问修饰符,返回值类型,方法名,参数列表完全一样

一、作业

作业1: 详见项目day09/src/com/qf/homework/pdf6_t19

主要考察:属性封装,类继承,和方法重写

day09_面向对象_多态_static_第1张图片

这是UML类体. 实线箭头代表继承关系

作业2: 详见项目day09/src/com/qf/homework/pdf6_t24

主要考察:属性封装,类继承,和方法重写以及super的使用,还有基本的代码逻辑(如何算工资)

二、访问修饰符

访问修饰符又叫 访问权限符,访问控制

就是用来限制属性和方法的使用范围的,即类中的属性和方法在什么地方可以使用 什么地方不可以使用

所以就有了两个研究方向

  • 有哪些修饰符?
  • 都有哪些地方?
当前类中 同一包下其他类 其他包子类内 其他包非子类
public(公开公共) 自己能用,子对象能用
protected(受保护) 自己不能用,子类对象能用 ×
缺省(默认)(不写) × ×
private(私有) × × ×

总结: 访问修饰符有访问大小范围:

public > protected > package > private

延伸: 子类重写父类方法,子类的访问修饰符 >= 父类访问修饰符

三、static

3.1 介绍

static 修饰符, 意思是静态的, 静态的一旦设置值就可以被所有对象使用

  • 修饰属性
  • 修饰方法
  • 修饰内部类(了解)

作用:

  • 被static修饰的属性或者方法在内存只有一个
  • 被static修饰的属性或者方法,就会被所有对象共享
  • 会随着类(class字节码文件)加载而初始化

回忆以前(没有static时)

  • 一个类创建的多个对象和对象的关系? 相互独立互不影响
  • 对象和属性和方法的关系, 每次创建一个对象,对象都有属于自己的属性和方法

static特性

  • 凡是被static修饰的属性和方法,会随着class文件加载到内存而初始化
    • 其他的普通成员变量是随着创建对象,在堆中出现初始化
    • 静态的属性和方法会先出现,即没有创建对象时可以被使用了
    • 有静态修饰的属性和方法时 不一定有对象
  • 凡是被static修饰的属性和方法,在内存只有一份,被该类的所有对象共享

总结

  • 不加静态的属性和方法通过对象调用
  • 加了静态的属性和方法都通过类名调用
  • 静态方法可以直接调用静态的方法和属性
  • 静态方法不能直接调用非静态方法
  • 非静态方法能调用静态属性和方法
  • 静态方法内不能使用this

3.2 演示

黄牛卖演唱会票,假设100张票,多个黄牛在卖

public class Huangniu {
    /**
     * 属性不加static,那就是成员变量,又叫对象属性
     * 叫对象属性是因为,每次创建对象,每个对象都有该属性
     * 成员变量/对象属性是在内存堆中
     * -----------------------------------------
     * 但是加上static,不再是对象属性,即不属于每个对象,也不存在于堆中
     * 而是在
     */
    static int ticket = 100;
    String name;
    // 卖票
    public void sellTicket(){
        System.out.println("黄牛卖票" );
        ticket--;
    }
}
public class TestHuangniu {
    public static void main(String[] args) {
        // 找到黄牛
        Huangniu niu1 = new Huangniu( );
        // 先看有多少张票
        // System.out.println(niu1.ticket );
        // 静态的属性建议使用类名调用
        System.out.println(Huangniu.ticket );

        // 卖一张
        niu1.sellTicket();
        // 再看一眼余票
        System.out.println( niu1.ticket);
        System.out.println("----------------" );

        // 再找到黄牛,卖票
        Huangniu niu2 = new Huangniu( );
        // 查看余票
        System.out.println(niu2.ticket );

        System.out.println("------------------" );

        // toString就是静态方法,类名直接调用
        Arrays.toString(new int[]{1});
        // PI就是静态属性,类名直接调用
        System.out.println(Math.PI );
    }
}

day09_面向对象_多态_static_第2张图片

3.3 应用场景

  1. 将一些方法或者属性定义成静态,方便调用,因为类名直接调用
    例如: Arrays.toString, Math.PI
  2. 当有些时候确实需要某个数据被共享时,就加上静态
    例如: 火车票

四、多态

4.1 介绍

多态: 同一种东西多种形态

面向对象中的多态: 特指某个方法,运行得到不同的结果 (同一个对象调用同一个方法结果却不一样)


如何做?要同时满足三个条件

  • 继承
  • 重写
  • 父类引用指向子类对象(向上转型)(把子类包装成父类)

为什么要多态?有什么好处?

  • 提高代码扩展性
  • 兼容性
  • 降低耦合性

4.2 演示

day09_面向对象_多态_static_第3张图片

4.3 关于多态的应用场景

  1. 方法的参数列表是父类,传参数传入子类对象,让该方法展现多态
public class TestPoly {

    public static void main(String[] args) {
        // 父类引用指向父类对象(自己引用指向自己对象)
        // Animal animal = new Animal( );

        // 子类引用指向子类对象(自己引用指向自己对象)
        // Dog dog = new Dog( );

        // 父类引用 指向 子类对象(向上转型)(将子类包装成父类)
        // Animal animal = new Dog( );
        // System.out.println(animal );
        Animal animal = new Cat();

        // eat方法就会出现多态
        animal.eat();
        System.out.println("-------------------" );
        dogShow(new Dog());
        catShow(new Cat());
        System.out.println("-------------------" );

        // 使用多态调用方法
        animalShow(new Dog());// 向上转型
        animalShow(new Cat());
        animalShow(new Pig());

    }

    /**
     * 设计方法,展示每个动物吃的东西
     */
    public static void dogShow(Dog dog){
        dog.eat();
    }
    public static void catShow(Cat cat){
        cat.eat();
    }
    // 如果再加动物,这里就需要再重新定义好多方法
    // 有了多态就可以解决这些问题
    // 将方法参数列表设计父类,传参数时传入子类对象(向上转型)
    // 这样就可以提高代码扩展性,大大减少了耦合性
    public static void animalShow(Animal animal){
        animal.eat();
    }
}
  1. 方法的返回值是父类,允许返回子类对象
class Animal {
}

class Dog extends Animal {
}

class Cat extends Animal {
}

public class TestAnimal {
    public static Animal getAnimal() {
        //1
        // return null; // ok
        // return new Animal(); // ok
         return new Cat(); // ok
        //return new Dog(); // ok
    }

    public static void main(String args[]) {
        Animal animal = getAnimal( );
        System.out.println(animal );
    }
}

day09_面向对象_多态_static_第4张图片

  1. 利用多态性,设计父类类型的数组,存储子类对象
public class TestShape {

    public static void main(String[] args) {

        // 创建父类类型数组
        // 数据类型[] 数组名 = new 数据类型[长度];
        Shape[] shapes = new Shape[3];

        // 存储的是子类对象
        Circle circle = new Circle( );
        circle.setR(10);
        shapes[0] = circle;// 相当于向上转型

        // 子类对象circle赋值给父类类型shape的引用
        Rect rect = new Rect( );
        rect.setLength(10);
        rect.setWidth(5);
        shapes[1] = rect;

        Square square = new Square( );
        square.setL(10);
        shapes[2] = square;

        for (int i = 0; i < shapes.length; i++) {
            Shape shape = shapes[i];// 取值
            // 运行看子类
            double area = shape.area( );// 该方法会展现多态性
            double girth = shape.girth( );// 该方法会展现多态性
            System.out.println("面积:" + area );
            System.out.println("周长:" + girth );
            System.out.println("----------" );
        }
    }
}

day09_面向对象_多态_static_第5张图片

4.4 注意事项

多态方法运行的注意事项

  • 父类引用调用的方法如果子父类都有,那么就是展示子类的(运行看子类)
  • 父类引用调用的方法父类有,子类没有 ----> 允许(编译看父类)
  • 编译看父类,运行看子类
    • 父类引用调用的方法,父类得有该方法,父类没有的话编译就报错
    • 父类引用调用的方法,子类中有,那么就运行子类的
      • 子类中没有该方法,就运行父类的

五、总结

关于访问修饰符 ,见到认识,知道什么效果即可
static,见到认识,知道类名可以直接调用静态方法和属性
重点还是多态,重点在于使用多态(参数,返回值,数组),重点在于题
写题口诀
	多态前提: 继承,重写,向上转型
	编译看父类,运行看子类

六、作业

t22
t25

你可能感兴趣的:(#,Java2313,java,开发语言)