Java学习笔记(11)

面向对象进阶

Static

静态变量

所有对象一起共享,就用static修饰

不属于对象,属于类的 可以用 类名.静态变量 = "";赋值

但是 对象.静态变量也可以访问到内容

Static内存图

Student这个类的字节码文件加载到方法区,并在内存中创建了一个单独存放静态变量的空间,叫做静态区(JDK8之前是在方法区里的,之后就在堆内存中)。

静态区存放所有的静态变量。

此时,堆内存中还没有对象,因为没有new关键字出现。

所以,静态变量是随着类的加载而加载的,优先于对象出现的

对象空间里则存储所有非静态的成员变量。

静态方法

Javabean类 测试类 工具类

为什么要私有化?

为了不让创建对象,创建出来的对象没有意义,所以直接设为private

java 复制代码
package exercise;

import java.util.StringJoiner;

public class ArrayUtil {
    private ArrayUtil() {
    }

    public static String printArr(int[] arr) {
        StringJoiner sj = new StringJoiner(", ", "[", "]");
        for (int i = 0; i < arr.length; i++) {
            sj.add(arr[i] + "");
        }
        return sj.toString();
    }

    public static double getAverage(double[] arr) {
        double sum = 0;
        for (int i = 0; i < arr.length; i++) {
            sum += arr[i];
        }
        return sum / arr.length;
    }



}
java 复制代码
public static int getMaxAge(ArrayList<Student> arrayList) {
        int maxAge = arrayList.get(0).getAge();
        for (int i = 1; i < arrayList.size(); i++) {
            int age = arrayList.get(i).getAge();
            maxAge = maxAge > age ? maxAge : age;
        }
        return maxAge;
    }

静态方法中没有this

因为,静态方法中一般都是对象共享的,与某个对象是没有关系的

this表示当前方法调用者的地址值,而静态方法不能被对象调用(只能被类调用),所以静态方法中就不存在this

而非静态方法中,方法是通过对象来调用的,所以在方法的形参中会有一个隐藏的this来表示当前调用者的地址值,通常都会省略这个this不写。

静态中用this会报错,不知道是调用的谁的name

Main方法

继承

父类 子类

什么时候用?

继承特点

如果一个父类中的方法中使用了private,则子类就不能访问这个方法,只有在本类中才能用

所以,子类只能访问父类中非私有的成员

构造方法不能继承

成员变量都能继承,但是子类不能直接用

继承内存

方法区中加载该类的字节码文件,如果该类有父类,则要一同添加到方法区

创建新的类对象,如果该类是有继承父类的,则对象中会把空间分为两块

一块用来存父类的成员变量,一块存子类的成员变量

如果父类的成员变量变为私有private

能继承,但子类无法直接赋值

成员方法能否被继承

虚方法表:父类给子类的,包含经常用到的方法

只有虚方法才能被继承

Object有5个方法可以加载到虚方法表里

父类的private方法不能被继承

准确讲,父类中只有虚方法表中的成员方法能够被子类继承

继承中成员变量的特点

Name前面没有东西,就近原则

This.name 就是本类的成员变量name

Super.name 就是父类的成员变量name

子类中一次只能调用一个super,没有super.super.name

继承中成员方法的访问特点

一样是就近原则

This,super分别访问子类和父类的

重写父类的方法

方法重写的本质:子类覆盖了从父类继承的虚方法表里的方法

重写的时候,如果父类的方法比较多,可以直接super.eat();执行父类的方法

后面再写上子类的添加的重写内容

如果完全用不上父类的方法,就不用写super了,直接写上子类要重写的方法

方法重写总结

构造方法在继承中的访问方法

Super():默认调用父类的无参构造,一定要写在第一行,可以不写

Super(name,age):调用父类的有参构造,必须手写出来

This,super总结

This()同样要写在第一行,其实就是在调用空参构造时,给一个默认值,这样成员变量就不是空值了

练习

java 复制代码
package exercise2;

public class Test {
    public static void main(String[] args) {
        Lecturer lecturer = new Lecturer();
        lecturer.work();
        String name = lecturer.getName();
        System.out.println(name);
    }
}

package exercise2;

public class Employee {
    private String id;
    private String name;

    public Employee() {
    }

    public Employee(String id, String name) {
        this.id = id;
        this.name = name;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void work(){
        System.out.println("员工在工作!");
    }
}

package exercise2;

public class Teacher extends Employee{
    public Teacher() {
    }

    public Teacher(String id, String name) {
        super(id, name);
    }

}

package exercise2;

public class AdminStaff extends Employee{
    public AdminStaff() {
    }

    public AdminStaff(String id, String name) {
        super(id, name);
    }
}

package exercise2;

public class Lecturer extends Teacher{
    public Lecturer() {
        this(null,"zhansan");
        System.out.println("1111");
    }

    public Lecturer(String id, String name) {
        super(id, name);
    }

    @Override
    public void work() {
        super.work();
        System.out.println("讲师在教书");
    }
}

package exercise2;

public class Tutor extends Employee{
    public Tutor() {
    }

    public Tutor(String id, String name) {
        super(id, name);
    }

    @Override
    public void work() {
        super.work();
        System.out.println("助教在准备ppt");
    }
}

package exercise2;

public class Maintainer extends AdminStaff{
    public Maintainer() {
    }

    public Maintainer(String id, String name) {
        super(id, name);
    }

    @Override
    public void work() {
        super.work();
        System.out.println("维护专员在维护");
    }
}

package exercise2;

public class Buyer extends AdminStaff{
    public Buyer() {
    }

    public Buyer(String id, String name) {
        super(id, name);
    }

    @Override
    public void work() {
        super.work();
        System.out.println("采购员工在采购");
    }
}

多态

没有继承就没有多态

创建子类的对象赋值给父类的类型

多态

调用成员变量:编译看左边,运行也看左边

调用成员方法:编译看左边,运行看右边

多态

方法区在加载字节码文件,都是先加载父类的字节码文件,再加载子类的字节码文件

多态的优势

多态的弊端

不能调用子类的特有方法

如果要用,就要转换子类类型

A instanceof B:判断A是不是B类型的,返回true/false

JDK14之后

A instanceof B d:判断A是不是B类型的,如果是则转换为B类型,转换之后变量名为d,返回true/false

总结

根据需求完成代码:

1.定义狗类

属性:

年龄,颜色

行为:

eat(String something)(something表示吃的东西)

看家lookHome方法(无参数)

2.定义猫类

属性:

年龄,颜色

行为:

eat(String something)方法(something表示吃的东西)

逮老鼠catchMouse方法(无参数)

3.定义Person类//饲养员

属性:

姓名,年龄

行为:

keepPet(Dog dog,String something)方法

功能:喂养宠物狗,something表示喂养的东西

行为:

keepPet(Cat cat,String something)方法

功能:喂养宠物猫,something表示喂养的东西

生成空参有参构造,set和get方法

4.定义测试类(完成以下打印效果):

keepPet(Dog dog,String somethind)方法打印内容如下:

年龄为30岁的老王养了一只黑颜色的2岁的狗

2岁的黑颜色的狗两只前腿死死的抱住骨头猛吃

keepPet(Cat cat,String somethind)方法打印内容如下:

年龄为25岁的老李养了一只灰颜色的3岁的猫

3岁的灰颜色的猫眯着眼睛侧着头吃鱼

5.思考:

1.Dog和Cat都是Animal的子类,以上案例中针对不同的动物,定义了不同的keepPet方法,过于繁琐,能否简化,并体会简化后的好处?

2.Dog和Cat虽然都是Animal的子类,但是都有其特有方法,能否想办法在keepPet中调用特有方法?

java 复制代码
package exercise;

public class Test {

    public static void main(String[] args) {
        Person keeper1 = new Person("老王", 30);
        Person keeper2 = new Person("老李", 25);

//        Cat cat = new Cat(3,"灰");
//        Dog dog = new Dog(2,"黑");

        Animal cat = new Cat(3, "灰");
        Animal dog = new Dog(2, "黑");

        keeper1.keepPet(dog, "骨头");
        keeper2.keepPet(cat, "鱼");
    }
}


package exercise;

public class Person {

    private String name;
    private int age;

    public Person() {
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public void keepPet(Dog dog, String something) {
        System.out.println("年龄为" + getAge() + "岁的" + getName() + "养了一只" + dog.getColor() + "颜色的" + dog.getAge() + "岁的狗");
        System.out.println(dog.getAge() + "岁的" + dog.getColor() + "颜色的狗两只前腿死死的抱住" + something + "猛吃");

    }

    public void keepPet(Cat cat, String something) {
        System.out.println("年龄为" + getAge() + "岁的" + getName() + "养了一只" + cat.getColor() + "颜色的" + cat.getAge() + "岁的猫");
        System.out.println(cat.getAge() + "岁的" + cat.getColor() + "颜色的眯着眼睛侧着头吃" + something);

    }

    public void keepPet(Animal animal, String something){
        System.out.println("年龄为" + getAge() + "岁的" + getName() + "养了一只" + animal.getColor() + "颜色的" + animal.getAge() + "岁的猫");
        System.out.print(animal.getAge() + "岁的" + animal.getColor());

        if (animal instanceof Cat cat){
            cat.eat("鱼");
            cat.catchMouse();
        } else if (animal instanceof Dog dog) {
            dog.eat("骨头");
            dog.lookHome();
        }


    }
}

package exercise;

public class Animal {
    private int age;
    private String color;


    public Animal() {
    }

    public Animal(int age, String color) {
        this.age = age;
        this.color = color;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }


    public void eat(String something){

    }
}

package exercise;

public class Cat extends Animal {
    public Cat() {
    }

    public Cat(int age, String color) {
        super(age, color);
    }

    public void eat(String something) {

        System.out.println("颜色的眯着眼睛侧着头吃" + something);
    }

    public void catchMouse() {
        System.out.println("猫在抓老鼠");
    }
}


package exercise;

public class Dog extends Animal {
    public Dog() {
    }

    public Dog(int age, String color) {
        super(age, color);
    }

    public void eat(String something) {
        System.out.println("颜色的狗两只前腿死死的抱住" + something + "猛吃");
    }

    public void lookHome() {
        System.out.println("狗在看家");
    }
}
相关推荐
运维小雅1 小时前
哪些因素会直观地影响到产品销量?
经验分享·笔记·媒体
非凡ghost1 小时前
FxSound:提升音频体验,让音乐更动听
前端·学习·音视频·生活·软件需求
抓饼先生1 小时前
Linux control group笔记
linux·笔记·bash
ue星空1 小时前
月2期学习笔记
学习·游戏·ue5
我没想到原来他们都是一堆坏人1 小时前
(未完待续...)如何编写一个用于构建python web项目镜像的dockerfile文件
java·前端·python
搞一搞汽车电子2 小时前
S32K3平台eMIOS 应用说明
开发语言·驱动开发·笔记·单片机·嵌入式硬件·汽车
萧邀人2 小时前
第二课、熟悉Cocos Creator 编辑器界面
学习
沙二原住民2 小时前
提升数据库性能的秘密武器:深入解析慢查询、连接池与Druid监控
java·数据库·oracle
Jerry&Grj2 小时前
SpringBoot埋点功能技术实现方案深度解析:架构设计、性能优化与扩展性实践
java·微服务·性能优化·springboot·架构设计·埋点技术
没有bug.的程序员2 小时前
Redis Stream:轻量级消息队列深度解析
java·数据库·chrome·redis·消息队列