JavaSE13-面向对象-封装继承多态

一、封装

1、概念

把不需要用户了解细节(隐私或者的特别复杂的细节)包装(隐藏)起来,只对外提供公共访问方式 。

2、封装作用:成员变量私有化(封装体现形式其中的一种)

使用private来修饰成员变量,提供对应的set/get方法提供刚刚的访问方式。

2.1 private

  • private是一个修饰符
  • 它可以用来修饰类中的成员变量或者成员方法
  • 被它修饰的成员变量只能在本类中访问, 不能在其他类中直接访问
public class Phone{
    private String brand;//在成员变量定义的前面加上private修饰
}

2.2 set/get方法

  • setXxx方法用来对成员变量赋值,所以方法参数一般是和这个成员变量是同一个数据类型,没有返回值。
  • getXxx方法用来获取成员变量的值,所以方法一般是没有参数,有返回值,返回值类型就是这个成员变量的数据类型。

注意:上面的Xxx代表成员变量名,遵循小驼峰命名规范

public class Phone{

    private String brand;
    
    public void setBrand(String brand){
        this.brand = brand;
    }
    public String getBrand(){
        return brand;
    }
    public Phone(String brand){
        this.brand = brand;
    }
}

3.this

  • this可以用来在局部变量和成员变量重名的时候区分他们,加了this的就是成员变量。
  • this代表当前对象

注意:我们只能在一个类的成员方法或者构造方法中去使用this

二、继承

1、概念

继承可以理解为:让两个类(事物)产生从属关系,有了从属关系子类就肯定会具有父类的特征(父类中的非私有成员),这样我们用类去描述一些事物的时候就可以更方便

  • 超类,父类都是同一个概念就是叫法不同
  • 派生类,子类都是同一个概念就是叫法不同

2、继承的格式

在子类名后面加extends 父类名

public class Dog extends Animal {
  //Dog就成为了Animal的一个子类
}

3、继承的优缺点及注意事项

3.1 优点

提高了代码的复用性

3.2 缺点

增加了类和类之间的耦合性。违背了高内聚,低耦合原则

3.3 注意事项

  • java中类只能单继承,一个类只能有一个父类,但是可以多层继承
  • 有实际的从属关系才可以继承,不能不合逻辑的任意继承。

4、继承后成员相关语法

4.1 成员变量

  1. 父类非私有的成员变量才会继承给子类。
  2. 父类中如果已经有了某个成员变量,我们不应该再在子类中定义同名的成员变量。否则可能会导致非常难排查的Bug。

4.2 成员方法

父类非私有的成员方法会继承给子类。

4.3 构造方法

  1. 构造方法不会继承给子类。
  2. 子类的构造中 必须使用super()调用 父类的构造并且要求在第一行(先要初始化,才能使用)。
  • 不管如何,子类的(有参或无参)构造方法每一次会默认调用父类的无参构造super()。
  • 因为父类中可能有成员变量,并且这个成员变量要继承给子类使用,但是所有的变量在使用之前必须先赋值。而父类的成员变量只能用父类的构造方法进行默认的初始化去赋值。
  1. 子类的构造默认都会在第一行使用super()调用父类的无参构造 。
  • 所以当父类没有无参构造的时候子类构造中会报错。
  • 解决方案是给父类加上无参构造或者在子类构造中显示的调用父类的有参构造。
  1. 继承的时候构造方法不会被继承:
    因为构造方法的方法名和类名必须相同。假设可以继承,父类的构造方法名与子类名肯定不一致,假设不成立。

5、方法重写

5.1 概念

  • 方法重写:当子类拥有父类继承下来的某个功能(成员方法),但是在子类中对这个方法的具体实现和父类不同。这个时候我们在子类中定义了一个和父类方法相同的方法(包括返回值类型,方法名,参数列表) ,这就叫做方法重写。
  • 方法重载:在同一个类中,方法名相同, 参数列表不同的方法才叫方法重载(与返回值无关)

5.2 注意事项

  1. 子类中方法的修饰符权限不能比父类的低(子类>=父类),(一般都相同)。
    权限修饰符 : private < 默认(什么都不写) < protected < public)
  2. 在重写方法的时候方法的返回值类型其实可以不同(子类=<父类)(一般都相同)。
    但是要求子类中方法的返回值类型必须是父类方法返回值类型的子类。
  3. 我们可以用 @Override 注解来校验是不是方法重写。
  4. 私有的方法不能被重写,因为私有的不会被继承

5.3 思考:overload和override的区别

  • 方法重载:在同一个类中,方法名相同,参数列表不同,和返回值无关
  • 方法重写:在子父类中,子类有一个和父类方法名相同,参数列表相同,返回值类型也相同的方法。这个就叫方法的重写

6、this和super

this就代表本类的,super就代表父类的

  1. 访问成员变量
    this.成员变量名 本类的成员变量
    super.成员变量名 父类的成员变量
  2. 访问成员方法
    this.成员方法名(参数) 调用本类的成员方法
    super.成员方法名(参数) 调用父类的成员方法
  3. 调用构造方法
    this(参数) 调用本类的构造方法
    super(参数) 调用父类的构造方法

三、多态

1.概念

同一个数据类型的不同对象 对同一种行为 会有多种不同的实现。
动物—猫和狗,对吃饭表现为狗吃狗粮、猫吃小鱼干

2.多态前提

  1. 子类重写了父类的方法
  2. 父类引用指向子类对象
    (创建的是一个子类的对象,并把该对象赋值给一个变量,这个变量的类型是其父类类型)
Animal a = new Dog();
Animal b = new Cat();

3.父类引用指向子类对象后成员访问的特点

  • 除了成员方法编译看左边,运行看右边。
  • 其他所有成员(成员变量)都是编译看左边,运行看左边。

解读:编译期间会去看左边(父类),看父类有没有这个成员方法。如果没有则直接报错,如果有则编译通过,不报错。运行期间,实际执行代码,看的是右边(子类),看子类中有没有重写该方法,如果有则执行子类中的该方法,如果没有则运行父类中的该方法。

4.多态应用场景

多态最大的应用场景其实就用在方法的参数上。在适当的时候把方法的参数类型定义成父类类型。调用方法的时候就可以传入任意的子类对象。提高了代码的复用性和可扩展性。

5.多态优缺点

优点:提高了代码的复用性和可扩展性
缺点:不能直接使用子类的成员。

6.向上转型 & 向下转型

6.1 向上转型

向上转型就是子类转父类。因为是绝对安全的所以会自动进行转换。

 Animal a = new Dog();

6.2 向下转型

向上转型就是父类转子类。因为不是绝对安全的所以必须使用强转的方式来进行转换。
注意:必须是这个子类的对象才可以转换成该子类,否则会出异常。猫不能转成狗

    Animal a = new Dog();
    Dog d = (Dog)a;

6.3 instance of进行类型判断

  • 在向下转型的时候为了保证安全我们可以使用instanceof进行类型判断。判断一个对象是否某个类的对象。如果是的话我们再把它转换成该类型,这样会更加安全。
  • 对象 instanceof 类名/接口名
  • 类型判断转型的目的:弥补多态不能调用子类特有成员的缺点。向下转型后就可以调用子类特有的成员(例如成员方法)。
//判断对象是否是某个类的对象,如果是结果为true,如果不是结果为false
    Animal a = new Dog();
    if(a instanceof Dog){
        //说明a是Dog这个类的对象,我们可以把他强转成Dog类型
        Dog d = (Dog)a;
}

7.思考题

class A {  
    public String show(D obj){  
    return ("A and D");  
    }   
    public String show(A obj){  
    return ("A and A");  
    }   
    }   
class B extends A{  

    public String show(B obj){  
    return ("B and B");  
    }  
    public String show(A obj){    //A obj = new B()
    return ("B and A");  
    }    
}  
class C extends B{}   
class D extends B{}

class  DynamicTest
{    
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(a1.show(b));  //a a
    System.out.println(a1.show(c));  //a a
    System.out.println(a1.show(d));  //a d

    System.out.println(a2.show(b));  //b a 编译看左边有没有满足的方法,运行看右边子类有没有重写该方法,如果有就执行子类中的该方法
    System.out.println(a2.show(c));  //b a         
    System.out.println(a2.show(d));  //a d

    System.out.println(b.show(b));   //b b
    System.out.println(b.show(c));   //b b
    System.out.println(b.show(d));   //a d
    
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值