java封装、继承和多态

封装

1.封装的定义

    Java中封装的实质就是将类的状态信息隐藏在内部,不允许外部程序直接访问,而是通过该类提供的方法来实现对隐藏信息的操作和访问。

2.封装的方式

private关键字来限制访问权限

1,保证属性安全-----主要使用setter实现封装的安全性
2,提供便捷访问方式,权限加大,使用getter来保障访问调用

3.封装的作用

1.便于使用者正确使用系统,防止错误修改属性
2.有助于系统之间的松耦合,提高系统独立性
3.提高软件的可重用性
4.降低了构建大型系统的风险

4.包

包名由小写字母组成,不能以圆点开头或结尾
包名之前最好加上唯一的前缀,通常使用组织倒置的网络域名
包名后续部分依不同机构内部的规范不同而不同

package cn.kgc.kb11  //表示当前类所在的包
import 包名.类名  //导入包

5.访问权限

public:公共的,范围是全工程可见。
protected:包私有 + 子类。
默认:包级私有,范围是同包 可见。
private:类私有,范围是类内部可见

6.类成员的访问修饰

在这里插入图片描述

7.static修饰符

static 可以用来修饰
1.成员变量:静态变量,可以直接通过类名访问。
2.成员方法:静态方法,可以直接通过类名访问。
3.代码块:静态代码块,当java虚拟机加载类时,就会执行该代码块。

代码封装示例

package cn.kgc.kb11;

/**
 * @Author ZhangPeng
 * @Date 2021/1/18
 * @Description 未封装的企鹅类
 */
public class Penguin {
    private String name;
    private int health;
    private int love;
    private String sex;

    public Penguin(){}
    public Penguin(String name,int health,int love,String sex){
        setName(name);
        setHealth(health);
        setLove(love);
        setSex(sex);
    }

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

    public void setHealth(int health){
        if(health < 0 || health > 100){
            System.out.println("输入的健康值不合法,默认值为:" + 50);
            health = 50;
        }
        this.health = health;
    }
    public int getHealth(){
        return this.health;
    }

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

    public void setSex(String sex){
        if (sex == null || !sex.equals("公") && !sex.equals("母")){
            System.out.println("性别输入不合法,默认值为:公");
            sex = "公";
        }
        this.sex = sex;
    }
    public String getSex(){
        return this.sex;
    }

    public void sayHello(){
        System.out.println("我叫" + name + ",我是一只" + sex + "企鹅,我的健康值为:" + health + ",我与主人的亲密度为:" + love);
    }


}

继承

1.什么是继承

子类继承父类的特征和行为,使得子类具有父类的各种属性和方法。或子类从父类继承方法,使得子类具有父类相同的行为。

特点:在继承关系中,父类更通用、子类更具体。父类具有更一般的特征和行为,而子类除了具有父类的特征和行为,还具有一些自己特殊的特征和行为。

在继承关系中。父类和子类需要满足is-a的关系。子类是父类。

表示父类和子类的术语:父类和子类、超类和子类、基类和派生类,他们表示的是同一个意思。

2.为什么需要继承?什么时候应该继承?

使用继承可以有效实现代码复用,避免重复代码的出现。定义出了共同的协议。

当两个类具有相同的特征(属性)和行为(方法)时,可以将相同的部分抽取出

怎么实现继承?

用extends(扩展)关键字来表示一个类继承了另一个类。

在父类中只定义一些通用的属性和方法。

子类自动继承父类的属性和方法,子类中可以定义特定的属性和方法。或子类重新定义父类的属性、重写父类的方法可以获得与父类不同的功能。

3.继承权限

					访问权限                              继承
private:           本类内部                             不能继承        
default  :         本类+同包                            同包子类可以继承           
protected :     本类+同包+不同子包        			   可以继承 
public :           公开                                 可以继承

4.super关键字

用法:

super() 调用父类的构造方法,只能出现在构造方法的第一行

super.方法名 super表示父类的对象,通过它去调用父类的方法

注意:在写类的时候,一定要写默认无参的构造方法,如果一个构造方法的

第一句既不是this(),也不是super()时,那么就会在这里隐含的调用
他的父类的无参的构造方法,即隐含的有super()。

概述

  1. 继承是面向对象思想的三大特性之一,使类与类之间产生特殊 - 一般的关系,即is-a关系。
  2. 继承是从已有类中派生出新的类,新的类能吸收已有类的属性和方法,并且能拓展新的属性和行为。
  3. 在Java中使用extends关键字表示继承,语法表示为: class 子类 extends 父类{}
  4. 子类被称为派生类,父类又被称为超类。
  5. 子类继承父类,表名子类是一种特殊的父类,子类拥有父类的属性和方法,并且子类可以拓展具有父类所没有的一些属性和方法。
  6. 子类即是不扩展父类,也能维持拥有父类的操作。

优缺点

继承的好处
    提高了代码的复用性
    提高了代码的维护性
    让类与类之间产生了关系,是多态的前提
缺点
    增加了耦合性
OOP思想开发原则:高内聚,低耦合
    耦合:类与类之间的关系
    内聚:自身完成事情的能力

java继承特点

Java只支持单继承,不支持多重继承操作(extends A,B,C..)

class A {}
class B {}
class C extends A,B {} // 错误的,一个子类继承了两个父类,Java中不允许

为什么只支持单继承?
    多继承会存在安全隐患,因为当继承的多个类都存在相同的属性或方法名相同方法体不同的方法,子类进行调用时,就会产生不知道该调用哪一个类中的方法的情况。

java支持多层继承(继承体系)

class A {}
class B extends A {}
class C extends B {}

如果想用这个继承体系的所有功能,那么就实用对底层的子类创建的对象。

继承注意点

成员变量和方法

    子类只能继承父类的所有非私有的成员变量和方法。可以继承public protected 修饰的成员,不可以继承private修饰的。
    但是可以通过父类中提供的public 的setter和getter方法进行间接的访问和操作private 的属性。
    对于子类可以继承父类中的成员变量和成员方法,如果子类中出现了和父类同名的成员变量和成员方法时,父类的成员变量会被隐藏,父类的成员方法会被覆盖。需要使用父类的成员变量和方法时,就需要使用super关键字来进行引用。
    隐藏是针对成员变量和静态方法,覆盖是针对普通方法。
    当创建一个子类对象时,不仅会为该类的实例变量分配内存,也会为它从父类继承得到的所有实例变量分配内存,即使子类定义了与父类中同名的实例变量。 即依然会为父类中定义的、被隐藏的变量分配内存。
    如果子类中的实例变量被私有了 ,其父类中的同名实例变量没有被私有,那么子类对象就无法直接调用该变量,但可以通过先将对象变量强制向上转型为父类型,在通过该对象引用变量来访问那个实例变量,就会得到的是父类中的那个实例变量。

构造器

    子类不能继承获得父类的构造方法,但是可以通过super关键字来访问父类构造方法。

    在一个构造器中调用另一个重载构造器使用this调用完成,在子类构造器中调用父类构造器使用super调用来完成。

    super 和 this 的调用都必须是在第一句,否则会产生编译错误,this和super只能存在一个。

    不能进行递归构造器调用,即多个构造器之间互相循环调用。

    如果父类有无参构造时,所有构造方法(包含任意有参构造)自动默认都会访问父类中的空参构造方法。(自带super();)。

  1. 因为继承的目的是子类获取和使用父类的属性和行为,所以子类初始化之前,一定要先完成父类数据的初始化。
  2. 在Java中,每个类都会默认继承Object超类,所以每一个构造方法的第一条默认语句都是super() 。

     如果父类没有无参构造,反而有其他的有参构造方法时,子类继承父类后,子类必须显式的创建构造器,不论子类的构造器是否和父类构造器中参数类型是否一致,都必须在子类的构造器中显式的通过super关键字调用和父类构造器相应参数的构造方法。否则编译都通不过。

多态

多态的基本介绍

    所谓多态就是指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并不确定,而是在程序运行期间才确定,即一个引用变量倒底会指向哪个类的实例对象,该引用变量发出的方法调用到底是哪个类中实现的方法,必须在由程序运行期间才能决定。因为在程序运行时才确定具体的类,这样,不用修改源程序代码,就可以让引用变量绑定到各种不同的类实现上,从而导致该引用调用的具体方法随之改变,即不修改程序代码就可以改变程序运行时所绑定的具体代码,让程序可以选择多个运行状态,这就是多态性。

多态的实现

实现条件

在刚刚开始就提到了继承在为多态的实现做了准备。子类Child继承父类Father,我们可以编写一个指向子类的父类类型引用,该引用既可以处理父类Father对象,也可以处理子类Child对象,当相同的消息发送给子类或者父类对象时,该对象就会根据自己所属的引用而执行不同的行为,这就是多态。即多态性就是相同的消息使得不同的类做出不同的响应。

Java实现多态有三个必要条件:继承、重写、向上转型。

继承:在多态中必须存在有继承关系的子类和父类。

重写:子类对父类中某些方法进行重新定义,在调用这些方法时就会调用子类的方法。

向上转型:在多态中需要将子类的引用赋给父类对象,只有这样该引用才能够具备技能调用父类的方法和子类的方法。

只有满足了上述三个条件,我们才能够在同一个继承结构中使用统一的逻辑实现代码处理不同的对象,从而达到执行不同的行为。

对于Java而言,它多态的实现机制遵循一个原则:当超类对象引用变量引用子类对象时,被引用对象的类型而不是引用变量的类型决定了调用谁的成员方法,但是这个被调用的方法必须是在超类中定义过的,也就是说被子类覆盖的方法。

实现形式
基于继承实现的多态

基于继承的实现机制主要表现在父类和继承该父类的一个或多个子类对某些方法的重写,多个子类对同一方法的重写可以表现出不同的行为。

基于接口实现的多态

    继承是通过重写父类的同一方法的几个不同子类来体现的,那么就可就是通过实现接口并覆盖接口中同一方法的几不同的类体现的。

    在接口的多态中,指向接口的引用必须是指定这实现了该接口的一个类的实例程序,在运行时,根据对象引用的实际类型来执行对应的方法。

    继承都是单继承,只能为一组相关的类提供一致的服务接口。但是接口可以是多继承多实现,它能够利用一组相关或者不相关的接口进行组合与扩充,能够对外提供一致的服务接口。所以它相对于继承来说有更好的灵活性。

示例
public class A {
    public String show(D obj) {
        return ("A and D");
    }
 
    public String show(A obj) {
        return ("A and A");
    } 
 
}
 
public class B extends A{
    public String show(B obj){
        return ("B and B");
    }
    
    public String show(A obj){
        return ("B and A");
    } 
}
 
public class C extends B{
 
}
 
public class D extends B{
 
}
 
public class Test {
    public static void main(String[] args) {
        A a1 = new A();
        A a2 = new B();
        B b = new B();
        C c = new C();
        D d = new D();
        
        System.out.println("1--" + a1.show(b));
        System.out.println("2--" + a1.show(c));
        System.out.println("3--" + a1.show(d));
        System.out.println("4--" + a2.show(b));
        System.out.println("5--" + a2.show(c));
        System.out.println("6--" + a2.show(d));
        System.out.println("7--" + b.show(b));
        System.out.println("8--" + b.show(c));
        System.out.println("9--" + b.show(d));      
    }
}

运行结果:

1--A and A
2--A and A
3--A and D
4--B and A
5--B and A
6--A and D
7--B and B
8--B and B
9--A and D
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值