Java--封装,继承,多态

发布时间:2023年12月18日

封装

? ? ? ? 就是把抽象出的数据[属性]和对数据的操作[方法]封装在一起,数据被保护在内部,程序的其他部分只有通过被授权的操作[方法],才能对数据进行操作。

封装步骤:

? ? ? ? 1.将属性进行私有化private [外部不能直接修改属性]

? ? ? ? 2.提供一个公共的set方法,用于对属性判断并赋值

? ? ? ? ? ? ? ? public void setXxx(类型 参数名) {

? ? ? ? ? ? ? ? ? ? ? ? 属性 = 参数名;

????????????????}

? ? ? ? 3.提供一个公共的get方法,用于获取属性的值

? ? ? ? ? ? ? ? public 数据类型?getXxx(){????????//权限判断

? ? ? ? ? ? ? ? ? ? ? ? return xx;?

????????????????}

public class Main {
    public static void main(String[] args) {
        Person p1 = new Person();
        p1.setName("小狗");
        p1.setAge(18);
        p1.setSalary(22222);
    }
}

class Person {
    public String name;
    private int age;
    private double salary;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        if (name.length() >= 2 && name.length() <= 6) {
            this.name = name;
        } else {
            System.out.println("名字不合法,请重新输入!");
            this.name = "打钩";
        }

    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        if (age >= 1 && age <= 120) {
            this.age = age;
        } else {
            System.out.println("年龄不合法,请重新设置!");
            this.age = 18;
        }

    }

    public double getSalary() {
        return salary;
    }

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

封装与构造器

????????????????

public class Main {
    public static void main(String[] args) {
        Person p1 = new Person();
        p1.setName("小狗");
        p1.setAge(18);
        p1.setSalary(22222);
    }
}

class Person {
    public String name;
    private int age;
    private double salary;

    //无参构造器
    public Person() {
    }
    //带三个属性的构造器
    public Person(String name, int age, double salary) {    //通过构造器下面的限制方法会失效
        this.name = name;
        this.age = age;
        this.salary = salary;

        //通过在构造器里写set下面的方法就不会失效
        setName(name);
        setAge(age);
        setSalary(salary);
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        if (name.length() >= 2 && name.length() <= 6) {
            this.name = name;
        } else {
            System.out.println("名字不合法,请重新输入!");
            this.name = "打钩";
        }

    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        if (age >= 1 && age <= 120) {
            this.age = age;
        } else {
            System.out.println("年龄不合法,请重新设置!");
            this.age = 18;
        }

    }

    public double getSalary() {
        return salary;
    }

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

继承

? ? ? ? 问题:如果两个类的属性和方法有很多是相同的,该怎么办?

? ? ? ? 这就用到了继承,解决代码的复用性问题,当多个类存在相同的属性(变量)和方法时,可以从这些类中抽象出父类,在父类中定义这些相同的属性和方法,所有的子类不需要重新定义这些属性和方法,只需要通过extends来声明继承父类即可。

继承的基本语法:

class 子类 extends 父类 {

}

子类就会自动拥有父类定义的属性和方法。

public class pupil extends student {
    public void ing() {
        System.out.println("小学生正在考试小学内容");
    }
}
public class graduated extends student{
    public void ing() {
        System.out.println("大学生正在考试大学内容");
    }
}
public class student {
    public String name;
    public int age;
    private double score;


    public double getScore() {
        return score;
    }

    public void setScore(double score) {
        this.score = score;
    }

    public void out() {
        System.out.println(name + "\n" + age + "\n" + score);
    }
}
public class test {
    public static void main(String[] args) {
        pupil p = new pupil();
        p.name = "银角";
        p.age = 6;
        p.setScore(66);
        p.out();
        p.ing();


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


        graduated g = new graduated();
        g.name = "金角";
        g.age = 18;
        g.setScore(88);
        g.out();
        g.ing();
    }
}

继承细节

? ? ? ? 1.子类继承了所有的属性和方法,非私有的属性和方法可以在子类直接访问,但是私有属性和方法不能在子类直接访问,要通过公共的方法去访问。

public class father {
    public int n1 = 100;
    protected int n2 = 200;
    int n3 = 300;
    private int n4 = 400;

    public father() {       //无参构造器
    }

    public int getN4() {    //父类提供的公共方法
        return n4;
    }

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

    protected void test200() {
        System.out.println("test200");
    }

    void test300() {
        System.out.println("test300");
    }

    private void test400() {
        System.out.println("test400");
    }

    public void calltest400() {     //父类再使用一个公共方法调用test400(),
        // 这样子类使用这个方法就可以调用test400()
        test400();
    }

}

public class son extends father{
    public son(){
        System.out.println("son()...");
    }

    public void sayok() {
        //非私有的属性和方法可以在子类直接访问
        //但是私有的属性和方法不能再子类直接访问
        System.out.println(n1 + " " + n2 + " " + n3);
        test100();;
        test200();
        test300();

        //test400();    会报错,要使用的话,通过父类提供的公共的方法去访问。
        calltest400();
        System.out.println("n4=" + getN4());

    }

}
public class test {
    public static void main(String[] args) {
        son son = new son();
        son.sayok();
    }
}

2.子类必须调用父类的构造器,完成父类的初始化。

当创建子类对象时,不管使用子类的那个构造器,默认情况下总会去调用父类的无参构造器 ,如果父类没有提供无参构造器,则必须在子类的构造器中使用 super 去指定使用父类的哪个构造器完成对父类的初始化工作,否则,编译不会通过。

3.如果希望指定去调用父类的某个构造器,则显式的调用一下:super(参数列表)

4.super在使用时,需要放在构造器的第一行。super只能在构造器中使用。

5.super()和this()都只能放在构造器的第一行,因此这两个方法不能共存在一个构造器。

6.Java所有类都是Object类的子类

7.父类构造器的调用不限于直接父类,将一直往上追溯直到Object类。

8.子类最多只能继承一个父类(指直接继承),即Java中是单继承机制。

? ? ? ? ? ? ? ? 现有一个A类,A extends B ,B extends C ,A,B,C 中都含有一个相同的属性 name ,现在创建一个对象,A a = new A(); a.name; 其中 name 是A,B,C 哪个类的name,结果应该按照下面的步骤来:

? ? ? ? 1.首先看子类是否有该属性,如果子类有,并且可以访问,则返回信息。

? ? ? ? 2.如果子类没有这个属性,就看父类有没有,有并且可以访问,就返回信息。

? ? ? ? 3.如果父类也没有,就按照这样一直往上查询直到Object类。

super关键字

? ? ? ? super代表父类的引用,用于访问父类的属性,方法,构造器。

1.访问父类的属性,但不能访问父类的private属性

2.访问父类的方法,但不能访问父类的private方法

3.访问父类的构造器,只能放在构造器的第一句,只能出现一句。

super.cal();? ? ? ? ? ? ? ? //找cal方法的顺序是直接找父类,跳过本类。

????????????????super的访问不限于直接父类,如果爷爷类和本类中有同名的成员,也可以使用super去访问爷爷类的成员;如果多个基类中都有同名的成员,使用super访问遵循就近原则。A->B->C

方法重写

? ? ? ? ? ? ? ? 方法重写就是子类有一个方法,和父类的某个方法的名称,返回类型,参数一样,那么我们就说子类的这个方法覆盖了父类的方法。

? ? ? ? ? ? ? ? 子类方法的返回类型和父类方法返回类型一样,或者是父类返回类型的子类,比如:父类 返回类型是 Object ,子类方法返回类型是String,

public Object test(){}? ? ? ? ? ? 和? ? ? ? ? public String test(){}

????????????????子类方法不能缩小父类方法的访问权限。

多态

? ? ? ? 方法或对象具有多种形态,多态是建立在封装和继承的基础之上的。重写和重载就体现多态。

对象的多态:

? ? ? ? 1.一个对象的编译类型和运行类型可以不一致。

? ? ? ? ? ? ? ? ? ? ? ? Animal animal = new Dog();????????{编译类型是Animal,运行类型是Dog}

? ? ? ? 2.编译类型在定义对象时,就确定了,不能改变。

? ? ? ? 3.运行类型时可以变化的。

? ? ? ? 4.编译类型看定义时 = 号 的左边,运行类型看 = 号 的右边。

向上转型

? ? ? ? 多态前提是:两个对象(类)存在继承关系。

? ? ? ? 多态的向上转型

本质:父类的引用指向了子类的对象

语法:父类类型 引用名 = new 子类类型();

特点:编译类型看左边,运行类型看右边

? ? ? ? 可以调用父类中的所有成员(需遵守访问权限)。

? ? ? ? 不能调用子类中特有成员。

? ? ? ? 最终运行效果看子类的具体实现。即调用方法时,按照从子类开始查找方法,然后调用,规则与前面讲的方法调用规则一致。

public class Animal {
    String name = "动物";
    int age = 18;

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

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

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

    public void show() {
        System.out.println("hello 你好");
    }
}
public class Cat extends Animal {
    @Override
    public void eat() {
        System.out.println("猫吃鱼");
    }

    public void catchMouse() {
        System.out.println("猫抓老鼠");
    }
}
public class test {
    public static void main(String[] args) {

        Animal animal = new Cat();
        Object obj = new Cat();
//        animal.catchMouse;        不能调用,因为在编译阶段,能调用那些成员,是由编译类型来决定的
    }
}

向下转型

? ? ? ? 语法:子类类型 引用名 = (子类类型)父类引用。

? ? ? ? 只能强转父类的引用,不能强转父类的对象。

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

        Animal animal = new Cat();
        Object obj = new Cat();
//        animal.catchMouse;        不能调用,因为在编译阶段,能调用那些成员,是由编译类型来决定的

        //向下转型就可以调用:子类类型 引用名 = (子类类型)父类引用
        Cat cat = (Cat) animal;
        cat.catchMouse();
    }
}

? ? ? ? 要求父类的引用必须指向的是当前目标类型的对象。

? ? ? ? 可以调用子类类型中所有的成员。

Ending:?

????????OK,本篇文章就到此结束了,非常感谢你能看到这里,所以如果你觉得这篇文章对你有帮助的话,请点一个大大的赞,支持一下博主,若你觉得有什么问题或疑问,欢迎私信博主或在评论区指出~? ? ??

文章来源:https://blog.csdn.net/eci__/article/details/134864628
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。