[从0开始学Java|第十三天]面向对象进阶(static&继承)

static

static-静态变量

static表示静态,是Java中的一个修饰符,可以修饰成员方法,成员变量

静态变量

例:

(源代码)

1.类名调用(推荐)

java 复制代码
package com.itheima.a01staticdemo1;

public class StudentTest {
    public static void main(String[] args) {
        //1.创建第一个学生对象
        Student s1 = new Student();
        s1.setName("张三");
        s1.setAge(23);
        s1.setGender("男");
        //新增:老师的姓名
        s1.teacherName = "阿伟老师";

        s1.study();
        s1.show();

        //2.创建第二个学生对象
        Student s2 = new Student();
        s2.setName("李四");
        s2.setAge(24);
        s2.setGender("女");

        s2.study();
        s2.show();
    }
}

2.对象名调用

java 复制代码
package com.itheima.a01staticdemo1;

public class StudentTest {
    public static void main(String[] args) {
        Student.teacherName = "阿伟老师";
        //1.创建第一个学生对象
        Student s1 = new Student();
        s1.setName("张三");
        s1.setAge(23);
        s1.setGender("男");
        //新增:老师的姓名
        //s1.teacherName = "阿伟老师";

        s1.study();
        s1.show();

        //2.创建第二个学生对象
        Student s2 = new Student();
        s2.setName("李四");
        s2.setAge(24);
        s2.setGender("女");

        s2.study();
        s2.show();
    }
}
java 复制代码
package com.itheima.a01staticdemo1;

public class Student {
    //属性:姓名   年龄   性别
    //新增:老师的姓名
    private String name;
    private int age;
    private String gender;
    //新增:老师的姓名
    public static String teacherName;

    public Student() {
    }

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

    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 String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    //行为
    public void study(){
        System.out.println(name + "正在学习");
    }

    public void show(){
        System.out.println(name + "," + age + "," + gender + "," + teacherName);
    }
}

(运行结果截图)

static内存图

第一步

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

第二步

第三步

第四步

第五步

第六步

第七步

第八步

static-静态方法和工具类

static表示静态,是Java中的一个修饰符,可以修饰成员方法,成员变量

静态方法

工具类

帮助我们做一些事情的,但是不描述任何事物的类

各个类及其区别:
使用规则

1.类名见名知意

2.私有化构造方法

方法定义为静态

练习:定义数组工具类

(源代码)

java 复制代码
package com.itheima.a02staticdemo2;

public class TestDemo {
    public static void main(String[] args) {
        //测试工具类中两个方法是否正确
        int[] arr1 = {1,2,3,4,5};
        String str = ArrayUtil.printArr(arr1);
        System.out.println(str);

        double[] arr2 = {1.5,3.7,4.9,5.8,6.6};
        double avg= ArrayUtil.getAverage(arr2);
        System.out.println(avg);
        
    }
}
java 复制代码
package com.itheima.a02staticdemo2;

public class ArrayUtil {
    //私有化构造方法
    //目的:为了不让外界创造他的对象
    private ArrayUtil() {}

    //需要定义为静态的,方便调用
    public static String printArr(int[] arr){
        StringBuilder sb = new StringBuilder();
        sb.append("[");
        for (int i = 0; i < arr.length; i++) {
            if(i == arr.length-1){
                sb.append(arr[i]);
            }else{
                sb.append(arr[i]).append(", ");
            }
        }
        sb.append("]");
        return sb.toString();
    }

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

(运行结果截图)

练习:定义学生工具类

(源代码)

java 复制代码
package com.itheima.a03staticdemo3;

public class Student {
    private String name;
    private int age;
    private String gender;

    public Student() {
    }

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

    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 String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }
}
java 复制代码
package com.itheima.a03staticdemo3;

import java.util.ArrayList;

public class StudentUtil {
    private StudentUtil(){}

    //静态方法
    public static int getMaxAgeStudent(ArrayList<Student> list){
        //1.定义一个参照物
        int max = list.get(0).getAge();

        //2.循环遍历集合
        for (int i = 0; i < list.size(); i++) {
            //i 索引
            int tempAge = list.get(i).getAge();
            if(tempAge > max){
                max = tempAge;
            }
        }

        //3.直接返回max
        return max;
    }
java 复制代码
package com.itheima.a03staticdemo3;

import java.util.ArrayList;

public class Test {
    public static void main(String[] args) {
        //1.创建一个集合用来存储学生对象
        ArrayList<Student> list = new ArrayList<>();

        //2.创建3个学生对象
        Student stu1 = new Student("zhangsan",23,"n男");
        Student stu2 = new Student("lisi",24,"女");
        Student stu3 = new Student("wangwu",25,"男");

        //3.把学生对象添加到集合中
        list.add(stu1);
        list.add(stu2);
        list.add(stu3);

        //4.调用工具类中的方法
        int maxAgeStudent = StudentUtil.getMaxAgeStudent(list);

        System.out.println(maxAgeStudent);


    }
}

(运行结果截图)

static的注意事项

-静态方法只能访问静态变量和静态方法

-非静态方法可以访问静态变量和静态方法,也可以访问非静态变量和非静态方法

-静态方法中是没有this关键字

总结:

静态方法中,只能访问静态.

非静态方法可以访问索所有.

静态方法中没有this关键字.

[从代码理解]

(源代码)

java 复制代码
package com.itheima.a04static4;

/*总结:
    静态方法中,只能访问静态.
    非静态方法可以访问索所有.
    静态方法中没有this关键字.*/

public class Student {
    String name;
    int age;
    static String teacherName;

    //this:表示当前方法调用者的地址值
    //这个this:是由虚拟机赋值的
    public void show1(Student this){
        System.out.println("this" + this);
        System.out.println(this.name + ", " + this.age + ", " + this.teacherName);

        //调用其他方法
        this.show2();
    }

    public void show2(){
        System.out.println("show2");
    }

    public static void method(){
        //System.out.println(this.name);
        //this.show1();
        System.out.println("静态方法");
    }
}
java 复制代码
package com.itheima.a04static4;

public class StudentTest {
    public static void main(String[] args) {
        Student.teacherName = "阿伟老师";

        Student s1 = new Student();
        System.out.println("s1:" + s1);
        s1.name = "张三";
        s1.age = 23;
        s1.show1();

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

        Student s2 = new Student();
        System.out.println("s2:" + s2);
        s2.name = "李四";
        s2.age = 24;
        s2.show1();
    }
}

(运行结果截图)

[从内存理解]

1.静态方法不能访问非静态

第一步

第二步

静态方法不能调用实例变量

第三步

静态方法不能调用非静态成员方法

2.非静态方法可以调用所有

第一步

第二步

第三步

第四步

第五步

总结

重新认识main方法

继承

继承的概述

什么是继承?

-Java中提供一个关键字extends,用这个关键字,我们可以让一个类和另一个类建立起继承关系

-Student 称为子类(派生类) Person 称为父类(基类或超类)

使用继承的好处

-可以把多个子类中重复的代码抽取到父类中了,提高代码的复用性

-子类可以在父类的基础上,增加其他功能,使子类更强大

什么时候用继承?

当类与类之间,存在相同(共性)的内容,并满足子类是父类中的一种,就可以考虑使用继承,来优化代码

例如:

小结

继承的特点和继承体系的设计

继承的特点

Java只支持单继承,不支持多继承,但支持多层继承

**单继承:**一个子类只能继承一个父类

**不支持多继承:**子类不能同时继承多个父类

**多层继承:**子类A 继承父类B,父类B 可以 继承父类C

每一个类都直接或者间接的继承于Object

继承体系的设计

总结

练习:继承的练习(自己设计一个继承体系)

(分析)

(源代码)

[Animal]

java 复制代码
package com.itheima.a01oopextendsdemo1;

public class Animal {

    //权限修饰符:
    //private:子类就无法访问了
    //私有:只能在本类中访问

    //注意事项:
    //子类只能访问父类中非私有的成员
    public void eat(){
        System.out.println("吃东西");
    }

    public void drink(){
        System.out.println("喝水");
    }

}

[Cat]

java 复制代码
package com.itheima.a01oopextendsdemo1;

public class Cat extends Animal{
    public void catchMouse(){
        System.out.println("抓老鼠");
    }
}

[Dog]

java 复制代码
package com.itheima.a01oopextendsdemo1;

public class Dog extends Animal{
    public void lookHome(){
        System.out.println("看家");
    }
}

[Ragdoll]

java 复制代码
package com.itheima.a01oopextendsdemo1;

public class Ragdoll extends Cat{

}

[LiHua]

java 复制代码
package com.itheima.a01oopextendsdemo1;

public class LiHua extends Cat{

}

[Husky]

java 复制代码
package com.itheima.a01oopextendsdemo1;

public class Husky extends Dog{
    public void breakHome(){
        System.out.println("哈士奇在拆家");
    }
}

[Teddy]

java 复制代码
package com.itheima.a01oopextendsdemo1;

public class Teddy extends Dog{
    public void touch(){
        System.out.println("泰迪又在蹭我的腿了");
    }
}

[Test]

java 复制代码
package com.itheima.a01oopextendsdemo1;

public class Test {
    public static void main(String[] args) {
        //创建对象并调用方法

        //1.创建布偶猫的对象
        Ragdoll rd = new Ragdoll();
        rd.eat();
        rd.drink();
        rd.catchMouse();

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

        //2.创建哈士奇的对象
        Husky h = new Husky();
        h.eat();
        h.drink();
        h.lookHome();
        h.breakHome();
    }
}

(运行结果截图)

总结

子类到底能继承父类中的哪些内容

子类到底能继承父类中的哪些内容?

构造方法是否可以被继承

父类的构造方法不能被子类继承

例如:

(源代码)

java 复制代码
package com.itheima.a02oopextendsdemo2;

public class Test {
    public static void main(String[]args){
        //利用空参构造创建子类对象
        Zi z1 = new Zi();

        //利用有参构造创建子类对象
        Zi z2 = new Zi("张三", 23);
    }
}

class Fu{
    String name;
    int age;

    public Fu(){}

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

}

class Zi extends Fu{
    //如果一个类中没有构造方法,虚拟机会自动的给你添加一个默认的空参构造
}

成员变量是否可以被继承

继承的内存图
[没有用private修饰]

第一步

第二步

第三步

第四步

第五步

第六步

第七步

[用private修饰]

第一步

第二步

第三步

第四步

第五步

第六步

第七步

成员方法是否可以被继承

只有父类中的虚方法才能被子类继承

继承的内存图

第一步

第二步

第三步

第四步

第五步

第六步

第七步

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

继承中:成员变量的访问特点

就近原则:谁离我近,我就用谁

先在局部位置找,本类成员位置找,父类成员位置找,逐级往上.

例:

(源代码)

java 复制代码
package com.itheima.a05oopextendsdemo5;

public class Test {
    public static void main(String[] args) {
        Zi zi = new Zi();
        zi.ziShow();
    }
}

class Fu{
    String name = "Fu";
}

class Zi extends Fu{
    String name = "Zi";
    public void ziShow(){
        String name = "zishow";
        System.out.println(name);
        System.out.println(this.name);
        System.out.println(super.name);
    }
}

(运行结果截图)

总结

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

直接调用满足就近原则:谁离我近,我就用谁

super调用,直接访问父类

例:

(源代码)

java 复制代码
package com.itheima.a06oopextendsdemo6;

public class Test {
    public static void main(String[] args) {
        Student s = new Student();
        s.lunch();
    }
}

class Person{
    public void eat(){
        System.out.println("吃米饭,吃菜");
    }

    public void drink(){
        System.out.println("喝开水");
    }
}

class Student extends Person{
    public void lunch(){
        //现在本类中查看eat和drink方法,如果有,就会调用子类的;如果没有,就会调用从父类中继承下来的eat和drink方法
        this.eat();
        this.drink();

        //直接调用父类中的eat和drink方法
        super.eat();
        super.drink();
    }
}

(运行结果截图)

方法的重写

当父类的方法不能满足子类现在的需求时,需要进行方法重写

书写格式:

在继承体系中,子类出现了和父类中一模一样的方法声明,我们就称子类这个方法是重写的方法.
@Override重写注解

1.@Override是放在重写后的方法上,校验子类重写时语法是否正确

2.加上注解后如果有红色波浪线,表示语法错误

3.建议重写方法都加@Override注解,代码安全,优雅!

例:

(源代码)

java 复制代码
package com.itheima.a06oopextendsdemo6;

public class Test {
    public static void main(String[] args) {
        overseasStudent s = new overseasStudent();
        s.lunch();
    }
}

class Person{
    public void eat(){
        System.out.println("吃米饭,吃菜");
    }

    public void drink(){
        System.out.println("喝开水");
    }
}

//留学生
class overseasStudent extends Person{
    public void lunch(){
        this.eat();//吃意大利面
        this.drink();//喝凉水

        super.eat();//吃米饭,吃菜
        super.drink();//喝开水
    }
    @Override
    public void eat(){
        System.out.println("吃意大利面");
    }
    @Override
    public void drink(){
        System.out.println("喝凉水");
    }
}
class Student extends Person{
    public void lunch(){
        //现在本类中查看eat和drink方法,如果有,就会调用子类的;如果没有,就会调用从父类中继承下来的eat和drink方法
        this.eat();
        this.drink();

        //直接调用父类中的eat和drink方法
        super.eat();
        super.drink();
    }
}

(运行结果截图)

方法重写的本质

子类覆盖了从父类当中继承下来虚方法表里的方法

如果发生了重写,则会覆盖

方法重写注意事项和要求

1.重写方法的名称,形参列表必须与父类中的一致.

2.子类重写父类方法时,访问权限子类必须大于父类(暂时了解:空着不写<protected>public)

3.子类重写父类方法时,返回值类型子类必须小于等于父类

4.建议:重写的方法尽量和父类保持一致

5.只有被添加到虚方法表中的方法才能被重写

练习:利用方法的重写设计继承结构

(分析)

(源代码)

[Dog]

java 复制代码
package com.itheima.a07oopextendsdemo7;

public class Dog {

    public void eat(){
        System.out.println("狗在吃狗粮");
    }

    public void drink(){
        System.out.println("狗在喝水");
    }

    public void lookHome(){
        System.out.println("狗在看家");
    }
}

[Husky]

java 复制代码
package com.itheima.a07oopextendsdemo7;

public class Husky extends Dog{
    public void breakHome(){
        System.out.println("哈士奇在拆家");
    }
}

[SharPei]

java 复制代码
package com.itheima.a07oopextendsdemo7;

public class SharPei extends Dog{
    //因为沙皮狗吃的狗粮和骨头
    //父类中的方法不能满足我们的需求,所以需要进行重写

    @Override
    public void eat(){
        super.eat();//吃狗粮
        System.out.println("啃骨头");
    }
}

[ChinessDog]

java 复制代码
package com.itheima.a07oopextendsdemo7;

public class ChinessDog extends Dog{
    //父类中的方法不能满足我们的需求,所以需要进行重写
    //中华田园犬完全用不到父类中的代码,所以不需要通过super进行调用

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

[测试类]

java 复制代码
package com.itheima.a07oopextendsdemo7;

public class DogTest {
    public static void main(String[] args) {
        //创建对象并调用

        Husky h = new Husky();
        h.eat();
        h.drink();
        h.lookHome();
        h.breakHome();

        ChinessDog cd = new ChinessDog();
        cd.eat();
        cd.drink();
        cd.lookHome();
    }
}

(运行结果截图)

总结

继承中的构造方法和this,super关键字

继承中:构造方法的访问特点

是什么?

1.父类中的构造方法不会被子类继承

2.子类中所有的构造方法默认先访问父类中的无参构造,再执行自己

为什么?

1.子类在初始化的时候,有可能会使用到父类中的数据,如果父类没有完成初始化,子类将无法使用父类的数据

2.子类初始化之前,一定要调用父类构造方法先完成父类数据空间的初始化

怎么调用父类构造方法的?

1.子类构造方法的第一行语句默认都是:super(),不写也存在,且必须在第一行

2.如果想调用父类有参构造,必须手动写super进行调用

例:

[无参构造]

(源代码)

[Person]

java 复制代码
package com.itheima.a08oopextendsdemo8;

public class Person {
    String name;
    int age;

    public Person() {
        System.out.println("父类的无参构造");
    }

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

[Student]

java 复制代码
package com.itheima.a08oopextendsdemo8;

public class Student extends Person{
    public Student(){
        //子类构造方法中隐藏的super(去访问父类的无参构造
        super();
        System.out.println("子类的无参构造");
    }

}

[Test]

java 复制代码
package com.itheima.a08oopextendsdemo8;

public class Test {
    public static void main(String[] args) {
        //创建学生对象
        Student s = new Student();
    }
}

(分析)

(运行结果截图)

[有参构造]

(源代码)

[Person]

java 复制代码
package com.itheima.a08oopextendsdemo8;

public class Person {
    String name;
    int age;

    public Person() {
        System.out.println("父类的无参构造");
    }

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

[Student]

java 复制代码
package com.itheima.a08oopextendsdemo8;

public class Student extends Person{
    public Student(){
        //子类构造方法中隐藏的super(去访问父类的无参构造
        super();
        System.out.println("子类的无参构造");
    }

    public Student(String name, int age) {
        super(name, age);
    }

}

[Test]

java 复制代码
package com.itheima.a08oopextendsdemo8;

public class Test {
    public static void main(String[] args) {
        //创建学生对象
        Student s = new Student("zhangsan",23);

        System.out.println(s.name + "," + s.age);
    }
}

(分析)

(运行结果截图)

总结

this,super关键字

this,super使用总结

**this:**理解为一个变量,表示当前方法调用者的地址值;

super:代表父类存储空间.

例:

练习:带有继承结构的标准javabean类

(源代码)

[Employee]

java 复制代码
package com.itheima.a10oopextendsdemo10;

public class Employee {
    //1.类名见名知义
    //2.所有的成员变量都需要私有
    //3.构造方法(空参 带全部参数的构造)
    //4.get/set

    private String id;
    private String name;
    private double salary;

    public Employee() {
    }

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

    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 double getSalary() {
        return salary;
    }

    public void setSalary(double salary) {
        this.salary = salary;
    }

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

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

[Manager]

java 复制代码
package com.itheima.a10oopextendsdemo10;

public class Manager extends Employee{
    private double bonus;

    //空参构造
    public Manager() {
    }

    //带全部参数的构造: 父类 + 子类
    public Manager(String id, String name, double salary, double bonus) {
        super(id, name, salary);
        this.bonus = bonus;
    }

    public double getBonus() {
        return bonus;
    }

    public void setBonus(double bonus) {
        this.bonus = bonus;
    }

    @Override
    public void work(){
        System.out.println("管理其他人");
    }
}

[Cook]

java 复制代码
package com.itheima.a10oopextendsdemo10;

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

    public Cook(String id, String name, double salary) {
        super(id, name, salary);
    }

    @Override
    public void work(){
        System.out.println("厨师正在炒菜");
    }
}

[Test]

java 复制代码
package com.itheima.a10oopextendsdemo10;

public class Test
{
    public static void main(String[] args) {
        //1.创建对象
        Manager m = new Manager("heima001","张三",15000,8000);
        System.out.println(m.getId() + "," + m.getName() + "," + m.getSalary() + "," + m.getBonus());
        m.work();
        m.eat();

        Cook c =  new Cook();
        c.setId("heima002");
        c.setName("李四");
        c.setSalary(8000);
        System.out.println(c.getId() + "," + c.getName() + "," + c.getSalary());
        c.work();
        c.eat();
    }
}

(运行结果截图)

相关推荐
小楼v2 小时前
如何实现AI生成应用部署功能
java·后端·ai·部署
望未来无悔2 小时前
系统学习算法 专题十九 优先级队列(堆)
java·算法
小虾米 ~2 小时前
JAVA引用类型
java·开发语言
星辰_mya2 小时前
Elasticsearch之中
java·服务器·数据库
lly2024062 小时前
C++ 循环
开发语言
fengxin_rou2 小时前
[Redis从零到精通|第三篇]:缓存更新指南
java·数据库·redis·spring·缓存
九转成圣2 小时前
告别肉眼解析!Java 递归实现 JSON 全路径自动化探测工具
java·自动化·json
_运维那些事儿2 小时前
skywalking链路追踪
java·运维·ci/cd·软件构建·skywalking·devops
范纹杉想快点毕业2 小时前
状态机设计模式与嵌入式系统开发完整指南
java·开发语言·网络·数据库·mongodb·设计模式·架构