面向对象——封装和继承

目录

1. 封装

2. 访问权限修饰符

2.1 类的访问权限修饰符

2.2 类成员的访问权限修饰符

3. 继承

4. super 关键字

4.1 super 关键字访问属性

4.2 super 关键字访问方法

4.3 super关键字访问构造方法

5. 子类继承

 6. super 关键字 和 this 关键字内存图

6. static 关键字

6.1 修饰属性

 

6.2 修饰方法

6.3 修饰代码块 

7. 静态关键字总结

8. 方法重写


1. 封装

封装:面向对象三大特征之一

属性私有:将所有的属性使用private访问权限修饰符修饰  表示此属性只能在本类中访问  其他类无法访问

方法公开:针对每一个属性编写一堆对方法

        getter方法  用于获取属性值

        setter方法  用于设置属性值

高内聚:本类中的信息应该与本类直接产生关联关系  不能间接关联  或者没有关联

低耦合:耦合度是指程序各个类  各个组件  模块  之间的紧密联系程度  降低耦合度有利于程序的扩展 以及 维护

public class Penguin {
    private String name;
    private char sex;
    private int health;

    public void setName(String name){
        this.name = name;
    }
    public String getName(){
        return name;
    }
    public void setSex(char sex){
        if(sex == '雌' || sex == '雄'){
            this.sex = sex;
        }else{
            System.out.println("性别赋值不合法,使用默认性别:雌");
            this.sex = '雌';
        }
    }
    public char getSex(){
        return sex;
    }
    public void setHealth(int health){
        if(health >= 0 && health <= 100){
            this.health = health;
        }else{
            System.out.println("健康值赋值不合法,使用默认值60");
            this.health = 60;
        }
    }
    public int getHealth(){
        return health;
    }
}

2. 访问权限修饰符

2.1 类的访问权限修饰符

默认不写:表示在本包中可以访问

public:任何位置都可以访问

2.2 类成员的访问权限修饰符

private:本类

默认不写:本类  本包

protect:本类  本包 以及 任何位置的子类中

public:任何位置

3. 继承

子类继承父类  子类与父类是 is--a 的关系,即:子类是父类

例如:笔记本电脑是电脑  台式电脑是电脑

继承是Java中实现代码重用的重要手段之一

Java中只支持单继承,即一个类只能有一个直接父类

父类:父类中书写各个子类共有的信息  即方法和属性

子类:子类中书写独有的信息和方法

继承关键字:extends

public class Pet {
    private String name;
    private int health;
    private int love;

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getHealth() {
        return health;
    }
    public void setHealth(int health) {
        this.health = health;
    }
    public int getLove() {
        return love;
    }
    public void setLove(int love) {
        this.love = love;
    }
    public void print(){
        System.out.println("宠物的名字是:" + name);
        System.out.println("宠物的健康值是:" + health);
        System.out.println("宠物的亲密值是:" + love);
    }
}
public class Dog extends Pet{
    private String strain;

    public String getStrain() {
        return strain;
    }
    public void setStrain(String strain) {
        this.strain = strain;
    }
    public Dog(){}
}
public class Penguin extends Pet{
    private String sex;

    public String getSex() {
        return sex;
    }
    public void setSex(String sex) {
        this.sex = sex;
    }
    public Penguin(){}
}
public class TestPet {
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.setName("大黄");
        dog.setStrain("哈士奇");
        dog.setHealth(100);
        dog.setLove(100);

        dog.print();
        System.out.println(dog.getStrain());

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

        Penguin penguin = new Penguin();
        penguin.setName("大白");
        penguin.setHealth(100);
        penguin.setSex("雌");
        penguin.setLove(100);

        penguin.print();
        System.out.println(penguin.getSex());
    }
}

4. super 关键字

4.1 super 关键字访问属性

super 关键字可以直接访问继承自父类的属性  前提要求  访问权限允许

public class Pet {
    protected String name;
    protected int health;
    protected int love;

    public void print(){
        System.out.println("宠物的名字是:" + name);
        System.out.println("宠物的健康值是:" + health);
        System.out.println("宠物的亲密值是:" + love);
    }
}
public class Penguin extends Pet {
    String sex;

    public Penguin(){}

    public Penguin(String name,int health,int love,String sex){
        this.sex = sex;
        super.name = name;
        super.health = health;
        super.love = love;
    }
}

4.2 super 关键字访问方法

super 关键字可以直接访问继承自父类的方法前提要求  访问权限允许

public class Pet {
    protected String name;
    protected int health;
    protected int love;

    public void print(){
        System.out.println("宠物的名字是:" + name);
        System.out.println("宠物的健康值是:" + health);
        System.out.println("宠物的亲密值是:" + love);
    }
}
public class Dog extends Pet {
    String strain;

    public void printDog(){
        print(); //
        System.out.println("狗狗的品种是:" + strain);
    }
}
public class Penguin extends Pet {
    String sex;

    public void printPenguin(){
        super.print();
        System.out.println("企鹅的性别是:" + sex);
    }
}

4.3 super关键字访问构造方法

访问父类构造方法  必须在子类构造的第一句(所以在一个构造方法中  不能同时使用 this 和 super 访问本类以及父类的构造)

子类中的每个构造方法,默认访问父类的无参构造方法

除非子类构造方法显示访问父类的有参构造方法

总结:子类构造方法必须访问父类的无参或有参构造方法中的一个

public class Pet {
    protected String name;
    protected int health;
    protected int love;

    public Pet(){  //无参构造
    
    }
    public Pet(String name,int health,int love){  //有参构造
        this.name = name;
        this.health = health;
        this.love = love;
    }
}
public class Dog extends Pet {
    String strain;

    public Dog(){
      
    }

    public Dog(String name,int health,int love,String strain){
        super(name,health,love);
        this.strain = strain;
    }
}
public class Cat extends Pet {
    String furColor;

    public Cat(){
    }

    public Cat(String name,int health,int love,String furColor){
        super(name, health, love);
        this.furColor = furColor;
    }
}

5. 子类继承

能够继承public 和 protected 修饰的属性和方法,不管子类和父类是否在同一个包里

能够继承默认权限修饰的属性和方法,但子类和父类必须在同一个包里 

 

不能继承private 修饰的属性和方法

不能继承父类的构造方法

 

 6. super 关键字 和 this 关键字内存图

在子类中,可以使用super关键字访问的内容,同时可以使用this访问

new 子类对象 会调用子类构造方法 在调用子类构造方法之前 必须先调用父类的构造方法(默认访问无参构造,除非显示访问有参构造)

 

1.调用父类构造方法的作用

用于将父类的属性初始化

无参构造初始化默认值

有参构造则是传参

2.关于调用父类构造方法

注意:调用父类构造方法不会创建父类对象 只是为了初始化父类属性值

3.super 和 this 的关系

super 表示父类的信息 是包含在this之内的 每一个子类对象中都会包含父类的属性信息

 

4.不能继承  却在内存中还有属性值

第一:按照这样记忆

第二:Java官方说明的

6. static 关键字

6.1 修饰属性

static 修饰的属性称之为静态变量(类变量)被static 修饰的属性在内存中只存在一份 不属于任何对象 而是属于整个类  可以被此类的所有对象共享

如果有每个对象都共同的数据 我们可以使用static 修饰 以节省内存空间

因为static修饰的内容,通常用于被多个对象共享数据的数据,所以这样的数据通常要求不能随意改变

关于静态变量访问:

因为静态变量不属于任何对象 故不推荐使用对象名加点访问 推荐使用类名加点访问

本类中  直接访问

其他类  通过类名加点访问            前提:访问权限必须允许

public class Person {
    static int capacity = 100; // 单位 L
    String name;
    public void getWater(){
        if(capacity > 0){
            capacity--;
            System.out.println(name + "接水1升,还剩余" + capacity + "升");
        }else{
            System.out.println("没水了,请注水");
        }
    }
    public static void main(String[] args) {
        Person zs = new Person();
        zs.capacity = 500 ;

        zs.name = "赵四";
        zs.getWater();

        System.out.println(zs.capacity);

        Person ln = new Person();
        ln.name = "刘能";
        ln.getWater();

        System.out.println(ln.capacity);

        Person gk = new Person();
        gk.name = "广坤";
        gk.getWater();

        System.out.println(gk.capacity);
    }
}
public class Student {
    String name;
    int age;
    static String country ="中华人民共和国";

    public static void main(String[] args) {
        Student stu1 = new Student();
        stu1.name = "赵四1";
        stu1.age = 20;

        System.out.println(stu1.country);

        stu1.country = "中国";

        Student stu2 = new Student();
        stu2.name = "赵四2";
        stu2.age = 20;

        System.out.println(stu2.country);

        Student stu3 = new Student();
        stu3.name = "赵四3";
        stu3.age = 20;

        System.out.println(stu3.country);
    }
}

 

6.2 修饰方法

静态与实例之间的访问规则:

静态方法中不能使用this 和 super

静态访问静态 直接访问

实例访问实例 直接访问

同级别相互直接访问

实例访问静态 直接访问

静态访问实例 必须先new 对象  例如main方法访问实例级别的信息 属性 和方法

public class TestStaticMethod {
    public static void m1(){
        System.out.println("静态方法m1");
    }                    
    public static void m2(){
        System.out.println("静态方法m2");
        m1();
    }
    public void m3(){
        m1();
        m2();
        System.out.println("实例方法m3");
    }
    public void m4(){
        System.out.println("实例方法m4");
        m3();
    }
    public static void main(String[] args) {
        m1();
        m2();
        TestStaticMethod testStaticMethod = new TestStaticMethod();
        testStaticMethod.m3();
        testStaticMethod.m4();
    }
}
public class Test {
    public static void main(String[] args) {
        TestStaticMethod.m1();
        TestStaticMethod.m2();

        TestStaticMethod tsc = new TestStaticMethod();
        tsc.m3();
        tsc.m4();
    }
}

6.3 修饰代码块 

static 修饰代码块: 称之为静态代码块 随着JVM 加载类而执行  因为类只加载一次  所以静态代码块也只执行一次

 

多个静态代码块按照书写顺序执行

 

类什么时候会被加载?

 

1.创建对象

2.访问此类中的任何静态信息

 

什么时候使用静态代码块:静态代码块通常来执行一些前置操作

        比如 数据库连接、数据初始化

普通代码块:随着对象的创建而执行 每创建一个对象就执行一次

public class TestStaticCode {
    static int num;
    static{
        System.out.println("静态代码块1");
    }
    static{
        System.out.println("静态代码块2");
    }
    {
        System.out.println("普通/实例 代码块1");
    }
    {
        System.out.println("普通/实例 代码块2");
    }
    public TestStaticCode() {
        System.out.println("无参构造方法");
    }
    public static void main(String[] args) {
        TestStaticCode tsc1 = new TestStaticCode();
//        TestStaticCode tsc2 = new TestStaticCode();

//        System.out.println(num);
    }
}

7. 静态关键字总结

 名词解释:

方法区:方法区是SUN公司指定的规范,是JVM内存的一块区域

永久代:是JDK 7 对方法区具体的名称

元数据 / 原空间:是JDK 8 方法区具体的名称

对象创建的过程:

1.先将此对象对应的class文件加载到方法区

    如果此类已经被加载  则直接执行第二部创建对象

    如果此类没有被加载  则先加载

    此时静态的属性将被初始化  有具体的值或者默认值

2.在堆中开辟空间  此时实例级别的属性将会初始化

3.将堆中的地址值赋值给栈中的引用  完成对象的创建

关于静态的和实例(动态)级别的

静态的数据会随着类的加载而存在  而且不会轻易回收  回收效率更低  但是只存在一份  也节省内存空间

实例级别的数据会随着对象的创建而存在  可以轻易回收  回收效率更高  但是每创建一个对象就单独存在一份

//静态类练习
public class Voter {
    String name;
    static int ticketCount = 100;

    public boolean voteFor(){
        if(ticketCount > 0){
            ticketCount--;
            System.out.println(name + "投了一票,还剩余" + ticketCount + "张票");
            return true;
        }else{
            System.out.println("投票结束");
            return false;
        }
    }

    public static void main(String[] args) {
        Voter zs = new Voter();
        zs.name = "赵四";
        zs.voteFor();

        Voter gk = new Voter();
        gk.name = "广坤";
        gk.voteFor();

        Voter dn = new Voter();
        dn.name = "大拿";
        dn.voteFor();

        for(int i = 1;i < 120;i++){
            Voter v1 = new Voter();
            v1.name = i + "号选民";
            if(!v1.voteFor()){ // == false
                break;
            }
        }
    }
}

8. 方法重写

方法重写 overrides

1.存在于父子类之间

2.方法名相同

3.参数列表相同

4.返回值相同  或者是其子类

5.访问权限不能严于父类  必须大于等于父类  不能窄化父类方法的访问权限

6.不能抛出或者声明比父类更多的异常

7.静态方法可以被继承 但是不能被重写

注解 @Override 此注解用于书写在方法上 表示此方法属于重写父类的方法 次注解可以帮助我们正确重写父类的方法

同时提高代码的阅读性

public class Pet {
    private String name;
    private int health;
    private int love;

    public String getName() {
        return name;
    }

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

    public int getHealth() {
        return health;
    }

    public void setHealth(int health) {
        this.health = health;
    }

    public int getLove() {
        return love;
    }

    public void setLove(int love) {
        this.love = love;
    }

    public void print(){
        System.out.println("宠物的名字是:" + name);
        System.out.println("宠物的健康值是:" + health);
        System.out.println("宠物的亲密值是:" + love);
    }

}
public class Dog extends Pet {
    private String strain;

    public String getStrain() {
        return strain;
    }

    public void setStrain(String strain) {
        this.strain = strain;
    }

    /**
     *  方法重写  Overrides
     *  1.存在父子类之间
     *  2.方法名相同
     *  3.参数列表相同
     *  4.返回值相同  或者是其子类
     *  5.访问权限不能严于父类  必须大于等于父类  不能窄化父类方法的访问权限
     *
     *  6.不能抛出或者声明比父类更多的异常
     *  7.静态方法可以被继承 但是不能被重写
     *
     *  注解 @Override 此注解用于书写在方法上 表示此方法属于重写父类的方法  次注解可以帮助我们正确重写父类的方法
     *  同时提高代码的阅读性
     */
    @Override
    public void print(){
        super.print();
        System.out.println("狗狗的品种是:" + strain);
    }

}
public class Penguin extends Pet {
    private String sex;  // alt + insert

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public void printPenguin(){
        super.print();
        System.out.println("企鹅的性别是:" + sex);
    }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值