(day7) 自学Java——面向对象进阶

文章介绍了Java编程中的一些基础知识,包括静态变量的使用,如何创建和使用工具类,以及继承和多态的概念。通过具体的代码示例展示了如何定义抽象类、接口以及内部类,并提供了方法重写的实践。此外,还探讨了方法区的工作原理和构造方法的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

1.static静态变量

​编辑

2.继承

​编辑

3.多态

4.包、final、权限修饰符、代码块

5.抽象类

6.接口

7.内部类


非原创,为方便自己后期复习

1.static静态变量

5dc8d4580b2249e868d0796231cfaac8.png

静态存储位置的数据是共享的

948c641f9516e4111510c41f16b3da8f.png

b17e30daec65b12a6c22c7e1c1ed6c25.png

0c8bc5fe5ece8d7388088e4420505128.png

练习:定义数组工具类

需求:在实际开发中,经常会遇到一些数组使用的工具类。

请按照如下要求编写一个数组的工具类:ArrayUtil

·提供一个工具类方法printArr,用于返回整数数组的内容。

返回的字符串格式如:[10,20,50,34,100](只考虑整数数组,且只考虑一维数组)

·提供这样一个工具方法getAerage,用于返回平均分。(只考虑浮点型数组,且只考虑一维数组)

·定义一个测试类TestDemo,调用该工具类的工具方法,并返回结果。

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("]");
        String result=sb.toString();
        return result;
    }

    public static double getAerage(double[]arr) {
        double result=0;
        for (int i = 0; i < arr.length; i++) {
            result=result+arr[i];
        }
        double result1=result/arr.length;
        return result1;
    }
}
public class TestDemo {
    public static void main(String[] args) {
        int[]arr={1,2,3,4,5,6,7};
        double[]arr1={1.1,2.3,3.4,6.5,7.5};
        String result=ArrayUtil.printArr(arr);
        double result1=ArrayUtil.getAerage(arr1);
        System.out.println(result);
        System.out.println(result1);
    }
}

练习:定义学生工具类

需求:定义一个集合,用于存储3个学生对象。学生类的属性为:name、age、gender。

定义一个工具类,用于获取集合中最大学生的年龄。

//学生类
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;
    }
}
//工具类
import java.util.ArrayList;

public class StudentUtil {
    private  StudentUtil(){}

    public static int getMaxAge(ArrayList<Student> list) {
        int max=list.get(0).getAge();
        for (int i = 1; i < list.size(); i++) {
            int age=list.get(i).getAge();
            if (max<age){
                max=age;
            }
        }
        return max;
    }
}
//测试类
import java.util.ArrayList;

public class TestDemo {
    public static void main(String[] args) {
        ArrayList<Student> list=new ArrayList<>();
        Student s1=new Student("张三",20,"男");
        Student s2=new Student("李四",21,"男");
        Student s3=new Student("王五",22,"男");
        list.add(s1);
        list.add(s2);
        list.add(s3);
        int result=StudentUtil.getMaxAge(list);
        System.out.println(result);
    }
}

static注意事项:

2.继承

0966b7c1b98377f9f220e65e0d3c81d2.pngb1cfd56e81ba1078eb25502b5b32e8f0.png

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

现在有四种动物:布偶猫、中国狸花猫、哈士奇、泰迪。

暂时不考虑属性,只要考虑行为。请按照继承的思想特点进行继承体系的设计。

四种动物分别有以下的行为:

·布偶猫:吃饭、喝水、抓老鼠

·中国狸花猫:吃饭、喝水、抓老鼠

·哈士奇:吃饭、喝水、看家、拆家

·泰迪:吃饭、喝水、看家、蹭一蹭

 678acedfc9cc5bbe912ad30d347e6718.png

public class Animal {
    public  void eat() {
        System.out.println("吃饭");
    }
    public  void drinkWater() {
        System.out.println("喝水");
    }
}

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

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

public class Ragdoll extends Cat{

}
public class LiHua extends Cat{
}

public class Husky extends Dog{
    public void breakHome(){
        System.out.println("哈士奇在拆家");
    }
}
public class Teddy extends Dog{
    public void touch(){
        System.out.println("泰迪蹭一蹭");
    }
}

成员变量无论是否私有,都可以继承父类,但是不能被调用(不能使用)。

如果想使用,需要用相应的get,set方法。

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

现在有三种动物:哈士奇、沙皮狗、中华田园犬暂时不考虑属性,只要考虑行为。

请按照继承的思想特点进行继承体系的设计。三种动物分别有以下的行为:

哈士奇:吃饭(吃狗粮)、喝水、 看家、拆家

沙皮狗:吃饭(吃狗粮、吃骨头)、喝水、看家

中华田园犬:吃饭(吃剩饭)、喝水、 看家

public class Dog {
    public void protectHome(){
        System.out.println("看家");
    }
    public void eat(){
        System.out.println("吃狗粮");
    }
    public void drinkWater(){
        System.out.println("喝水");
    }
}

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

public class SharPei extends Dog{
   //父类中的方法已经不满足需求了,所以方法重写
    @Override
    public void eat() {
        super.eat();
        System.out.println("沙皮狗吃骨头");
    }
}

public class ChineseDog extends Dog{
    //父类中的方法已经不满足需求了,所以方法重写
    @Override
    public void eat() {
        System.out.println("中华田园犬吃剩饭");
    }
}

//测试类
public class Test {
    public static void main(String[] args) {
        //创建对象并调用方法
        ChineseDog cd=new ChineseDog();
        cd.eat();
        Husky hs=new Husky();
        hs.eat();
        hs.breakHome();
        SharPei sp=new SharPei();
        sp.eat();
        sp.protectHome();
    }
}

 

 访问本类构造方法的使用场景:需要设置默认值的时候。

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

1.经理:成员变量:工号、姓名、工资、管理资金;成员方法:工作(管理其他人)、吃饭(吃白米饭)

2.厨师:成员变量:工号、姓名、工资;成员方法:工作(炒菜)、吃饭(吃米饭)

//员工类
public class Employe {
    private int workId;
    private String name;
    private double salary;

    public Employe() {
    }

    public Employe(int workId, String name, double salary) {
        this.workId = workId;
        this.name = name;
        this.salary = salary;
    }

    public int getWorkId() {
        return workId;
    }

    public void setWorkId(int workId) {
        this.workId = workId;
    }

    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("正在吃饭");
    }
}
//经理类
public class Managers extends Employe{
    private double bonus;

    public Managers() {
    }

    public Managers(int workId, String name, double salary) {
        super(workId, name, salary);
    }

    public double getBonus() {
        return bonus;
    }

    public void setBonus(double bonus) {
        this.bonus = bonus;
    }
    //方法重写

    @Override
    public void work() {
        System.out.println("经理在管理其他人");
    }
}
//厨师类
public class Cook extends Employe{
    public Cook() {
    }

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

    //方法重写

    @Override
    public void work() {
        System.out.println("厨师在炒菜");
    }
}
//测试类
public class Test {
    public static void main(String[] args) {
        //创建对象并调用方法
        Managers m=new Managers(1,"张三",8000);
        m.setBonus(10000000);
        System.out.println(m.getWorkId()+"\t"+m.getName()+"\t"+m.getSalary()+"\t"+m.getBonus());
        m.eat();

        Cook c=new Cook(2,"李四",4000);
        System.out.println(c.getWorkId()+"\t"+c.getName()+"\t"+c.getSalary());
        c.work();
        c.eat();

    }
}

3.多态

 

方法区,会先加载父类Animal,再加载子类Dog

多态的弊端: 不能使用子类的特有功能。如果要用,需要转换类型。

解决方法:进行类型转换

练习:根据需求完成代码

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中调用特有方法?

//动物类
public class Animal {
    private int age;
    private String colour;

    public Animal() {
    }

    public int getAge() {
        return age;
    }

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

    public String getColour() {
        return colour;
    }

    public void setColour(String colour) {
        this.colour = colour;
    }

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

    public void eat(String something){
        System.out.println("动物在吃");
    }
}
//狗类
public class Dog extends Animal{
    public void lookHome(){
        System.out.println("看家");
    }

    public Dog() {
    }

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

    @Override
    public void eat(String something) {
        System.out.println(getAge()+"岁的"+getColour()+"颜色的狗两只前腿死死的抱住"+something+"猛吃");
    }
}
//猫类
public class Cat extends Animal{
    public Cat() {
    }
    public Cat(int age, String colour) {
        super(age, colour);
    }

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

    @Override
    public void eat(String something) {
        System.out.println(getAge()+"岁的"+getColour()+"颜色的猫眯着眼睛侧着头吃"+something);
    }
}
//饲养员类
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.getColour()+"颜色的"+dog.getAge()+"岁的狗");
//        dog.eat(something);
//    }
//    public void keepPet(Cat cat,String something){
//        System.out.println("年龄为"+getAge()+"岁的"+getName()+"养了一只"+cat.getColour()+"颜色的"+cat.getAge()+"岁的猫");
//        cat.eat(something);
//    }
    //用多态实现以上代码
    public void keepPet(Animal a, String something) {
        if (a instanceof Dog) {
            Dog d = ((Dog) a);
            System.out.println("年龄为" + getAge() + "岁的" + getName() + "养了一只" + d.getColour() + "颜色的" + d.getAge() + "岁的狗");
            d.eat(something);
        }else if (a instanceof Cat){
            Cat c=((Cat)a);
            System.out.println("年龄为"+getAge()+"岁的"+getName()+"养了一只"+c.getColour()+"颜色的"+c.getAge()+"岁的猫");
            c.eat(something);
        }
    }
    }
//测试类
public class Test {
    public static void main(String[] args) {
        //创建对象并调用方法
//        Dog ad=new Dog(2,"黑");
//        Person p1=new Person("老王",30);
//        p1.keepPet(ad,"骨头");
//
//        Cat ac=new Cat(3,"灰");
//        Person p2=new Person("老李",25);
//        p2.keepPet(ac,"鱼");

        Animal ad=new Dog(2,"黑");
        Person p1=new Person("老王",30);
        p1.keepPet(ad,"骨头");

        Animal ac=new Cat(3,"灰");
        Person p2=new Person("老李",25);
        p2.keepPet(ac,"鱼");

    }
}

4.包、final、权限修饰符、代码块

 

5.抽象类

一个方法抽取到父类中,不确定方法体,用abstract关键字修饰(抽象方法),子类会被强制重写,否则就直接报错。抽象方法所在的类,就是抽象类。

练习:编写带有抽象类的标准Javabean类

青蛙frog                属性:名字、年龄        行为:吃虫子、喝水

狗Dog                   属性:名字、年龄        行为:吃骨头、喝水

山羊Sheep           属性:名字、年龄        行为:吃草、喝水

//动物类(父类)
public abstract class Animal {
    private int age;
    private String name;

    public Animal() {
    }

    public int getAge() {
        return age;
    }

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

    public String getName() {
        return name;
    }

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

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

    public abstract void eat();
    public void drinkWater(){
        System.out.println("动物在喝水");
    };
}
//青蛙类
public  class Frog extends Animal{
    public Frog() {
    }

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

    @Override
    public void eat() {
        System.out.println("青蛙吃虫子");
    }
}
//狗类
public class Dog extends Animal{
    public Dog() {
    }
    public Dog(int age, String name) {
        super(age, name);
    }

    @Override
    public void eat() {
        System.out.println("狗吃骨头");
    }
}
//山羊类
public class Sheep extends Animal{
    public Sheep() {
    }

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

    @Override
    public void eat() {
        System.out.println("山羊吃草");
    }
}

6.接口

接口是对行为的抽取

练习:编写带有接口和抽象类的标准Javabean类

我们现在有乒乓球运动员和篮球运动员,乒乓球教练和篮球教练。为了出国交流,跟乒乓球相关的人员都需要学习英语。

请用所有知识分析,在这个案例中,哪些是具体类,哪些是抽象类,哪些是接口?

乒乓球运动员:姓名,年龄,学打乒乓球,说英语

篮球运动员:姓名,年龄,学打篮球

乒乓球教练:姓名,年龄,教打乒乓球,说英语

篮球教练:姓名,年龄,教打篮球

思路一:

 思路二:

//people类
package Test1;
//把people类写成抽象类。
// 因为直接创建把顶层父类的对象此时没有意义,所以写成抽象的
public abstract class People {
    private String name;
    private int age;

    public People() {
    }
    public People(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 abstract class Athlete extends People{
    public abstract void study();
}
//乒乓球运动员类
public class PingPongAthlete extends Athlete implements SpeakEnglish{
    @Override
    public void study() {
        System.out.println("学打乒乓球");
    }

    @Override
    public void speak() {
        System.out.println("乒乓球运动员说英语");
    }
}
//篮球运动员类
public class BasketballAthlete extends Athlete{
    @Override
    public void study() {
        System.out.println("学打蓝球");
    }
}
//教练类
public abstract class Coach extends People{
    public abstract void teach();
}
//乒乓球教练类
public class PingPongCoach extends Coach implements SpeakEnglish{
    @Override
    public void teach() {
        System.out.println("教打乒乓球");
    }

    @Override
    public void speak() {
        System.out.println("乒乓球教练说英语");
    }
}
//蓝球教练类
public class BasketballCoach extends Coach{
    @Override
    public void teach() {
        System.out.println("教打蓝球");
    }
}
//说英语的接口
public interface SpeakEnglish {
    public abstract void speak();
}
//测试类
public class Test {
    public static void main(String[] args) {
        PingPongAthlete pp=new PingPongAthlete();
        pp.setAge(15);
        pp.setName("kinkin");
        System.out.println(pp.getAge()+","+pp.getName());
        pp.study();
        pp.speak();
        BasketballCoach bc=new BasketballCoach();
        bc.setAge(40);
        bc.setName("krit");
        System.out.println(bc.getAge()+","+bc.getName());
        bc.teach();
    }
}

7.内部类

 

 

在堆内存中,先创建外部类的空间,再创建内部类空间

outer.this获取了外部类对象的地址值

 new Outer.Inner()

new 的是Outer里的inner对象

局部内部类,跟局部变量相似

紫色框内是一个没有名字的类,Swim接口跟这个类是实现关系,new的是紫色框内的对象,()说明是空参构造

紫色框内是一个没有名字的类,Animal跟这个类是继承关系,Animal是这个类的父类,new的是紫色框内的对象,()说明是空参构造  

 method里面new Animal......的内容,可以看成是Animal的一个子类对象。

应用场景:使用某个类,只使用一次,单独定义一个类太麻烦,用匿名内部类的方法,可以简化代码。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值