JAVA封装|继承|多态

一,继承:面向对象的三大继承之一

子类 | 派生类 : 继承父类的类
定义子类独有的内容
父类 | 超类 | 基类 : 被子类继承的类
所有子类的共性

1,Q&A

1.为什么要使用继承 ?

为了提供代码的复用性

2.如何实现继承?

子类 extends 父类

class Fu{
}

class Zi extends Fu{//Zi类继承了Fu类
}

3.继承的作用 ?

子类一旦继承父类,就有权直接使用父类中的成员

public class Class001_Extends {
    public static void main(String[] args) {
        Teacher teacher = new Teacher("张三",33,"数学");

        teacher.sleep();
        teacher.teach();
    }
}

//父类
class Person{
    public String name;
    public int age;

    public Person(){}

    public void sleep(){
        System.out.println(name+"正在休息...");
    }
}

//子类
class Teacher extends Person{
    public String subject;

    public Teacher(){}

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

    public void teach(){
        System.out.println("教书育人...");
    }
}

4.注意 : 继承是单继承机制,但是接口可以多实现

一个子类只能存在一个直接父类

一个父类可以存在多个子类

5.单继承的优缺点 : 简单,但是不便于后期维护

2,this与super

this : 指代当前对象(new|调用成员方法的对象)

在构造器的首行通过this(实参)调用本类中的其他构造器

区分同名成员与局部变量问题

默认就近原则找局部

想要指代成员,需要通过this.调用成员

如果不存在同名问题,调用成员时,this.可以省略

//成员变量
private String name;
private int age;

//带参构造器
public Student(String name,int age){
    this.name=name;
    this.age=age;
}

super :指代父类对象

在子类构造器的首行通过super(实参)调用父类构造器
  1. 如果在子类构造器的首行没有通过super(实参)显示的调用父类的指定构造器,默认会调用父类空构造 super()

不能在子类构造器的首行同时通过this(实参)与super(实参)调用其他构造器,可以先执行this(实参),调用本类中其他构造器后,在其他构造器的首行通过super(实参)调用父类构造器

  1. 默认就近原则找子类的成员

  1. 通过super.调用的父类成员

成员的初始顺序 : 先静态后成员

子父类继承关系下创建子类对象 : 先父类后子类

public class Fu{
    String str="Fu类str";
}
public class Zi extends Fu{
    String str="子类str";
    public void test(){
        String str="局部str";
        System.out.println(str);  //局部
        System.out.println(this.str);  //子类成员str
        System.out.println(super.str); //父类str
        System.out.println(this);
    }
}

this与super都不能使用在static修饰的方法中

3,重写 override

3.1 重写与重载之间的区别 :

3.1.1.共同点 : 都是方法的重要特性
3.1.2.异同点 :
3.1.2.1实现重载的3个条件 :

1.一个类中的多个方法

2.方法名相同

3.参数列表|方法签名不同(方法签名:方法名+参数列表;是方法唯一的标识)

public class Student{

    //一个参数的构造器
    public void Student(String name){
        this.name=name;
    }

    //两个参数的构造器
    public void Student(String name,int age){
        this.name-name;
        this.age=age;
    }

}
3.1.2.2实现重写的3个条件 :

1.两个类中的两个方法

2.继承关系|实现关系

3.方法签名完全相同(方法签名:方法名+参数列表 ,是方法的唯一标识)

public class Class001_Override {
    public static void main(String[] args) {
        SiCong siCong = new SiCong();
        siCong.words();
    }
}

class JianLin{
    public String name = "王健林";

    //名言
    public JianLin words(){
        System.out.println("先定一个小目标,挣它一个亿....");
        return null;
    }
}

class SiCong extends JianLin{
    public String name = "王思聪";

    //重写
    @Override
    public SiCong words(){
        System.out.println("我不在乎我的朋友有钱没钱,反正都没我有钱!!!!");
        return null;
    }
}

3.2 重写方法的定义需求 :

子类从父类中继承功能(方法),方法满意,方法体实现子类不满意,就可以在子类中对这个方法进行重新实现--->方法的重写

3.3 方法的调用 :

通过子类对象,调用子类中重写的方法,对父类中的被重写的方法进行屏蔽

如果没有重写方法,会顺着继承体系,到父类中查找,如果都没有,会报错

3.4 如何检查方法是否为重写方法 :

1.行号的后面显示O+箭头,点击跳转到重写方法|被重写方法上

2.重写方法上添加一个注解: @Override

3.5 重写方法的细节要求 :

== : 方法签名要求完全相同

<= : 返回值类型 :

基本数据类型|void : 返回值类型要求完全相同

引用数据类型 : 子类中的重写方法的返回值类型<=父类中的被重写方法的返回值类型

>= : 权限修饰符 : 子类中重写的权限修饰符>=父类中被重写方法的权限修饰符

3.6 注意 :

继承 : 延续+扩展

不能被重写的方法 :

1.被private修饰的方法不能被重写

2.被final修饰的方法不能被重写

3.被static修饰的方法不能被重写

如果子类中出现于父类静态方法同名的方法,要求也要被static修饰

二,封装

1.访问权限修饰符 :

控制被修饰的成员被访问的权限

成员修饰符,只能修饰成员不能修饰局部

分类

本类中

同包类

不同包下子类

其他类

public 公共的

protected 受保护的

default 默认的(省略)

private 私有的

可以修饰类的访问权限修饰符为 : public default

最常用的两个访问权限修饰符 : public private

protected修饰的成员的使用 :

1)同包下类使用

2)在不同下的子类中,通过继承关系访问

package homework.homework0223.modifier;

public class Class001_Modifier {
    public String testPublic="public";
    private String testPrivate="private";
    protected String testProtected="rotected";
    String testDefault="default";

    public static void main(String[] args) {
        //测试本类中能否使用
        Class001_Modifier cm=new Class001_Modifier();
        System.out.println(cm.testPublic);
        System.out.println(cm.testDefault);
        System.out.println(cm.testPrivate);
        System.out.println(cm.testProtected);
    }
}


//同包类
class Demo{
    public static void main(String[] args) {
        //测试同包类
        Class001_Modifier cm=new Class001_Modifier();
        System.out.println(cm.testPublic);
        System.out.println(cm.testDefault);
        //protect只能在同类下使用
        //System.out.println(cm.testPrivate);
        System.out.println(cm.testProtected);
    }
}
import com.yjxxt.modifier02.Class001_Modifier;

//不同包下的子类
public class OtherSon extends Class001_Modifier {
    public static void main(String[] args) {
        //1)不同包下的子类中使用  2)通过父类对象访问-->不能访问父类中被protected修饰的成员,因为不是通过继承关系访问
        Class001_Modifier cm = new Class001_Modifier();
        System.out.println(cm.testPublic);

        //1)不同包下的子类中使用  2)通过子类对象访问
        OtherSon son = new OtherSon();
        System.out.println(son.testPublic);
        System.out.println(son.testProtected);
    }
    //成员方法
    public void test(){
        System.out.println(testPublic);
        //1)不同包下的子类中使用      2)通过继承关系
        System.out.println(testProtected);
    }
}

//不同包下的其他类
class Other{
    public static void main(String[] args) {
        //测试不同包下的其他类中使用
        Class001_Modifier cm = new Class001_Modifier();
        //System.out.println(cm.testPrivate);
        //System.out.println(cm.testDefault);
        //System.out.println(cm.testProtected);
        System.out.println(cm.testPublic);
    }
}

面向对象的设计原则之一 : 开闭原则 (对修改关闭,对扩展开放)

三,多态

多态 : polymorphic --> 面向对象三大特性之一

一种事物的多种形态|多种表现形式|多种实现方式

行为多态 : 一个功能的不同实现方式

1.多态的最终体现 :

父类的引用指向子类对象
public static void main(String[] args){
    //父类引用指向子类对象,发生了多态
    Fu fu=new Zi();
} 

class Fu{

}

class Zi extends Fu{
    
}

2.多态的前提 :

继承关系|实现关系

3.多态调用 :

  1. 多态引用调用会调用子类中重写的方法,对子类新增内容不可见

  1. 多态调用成员变量 : 编译运行看父类|左边|类型

  1. 多态调用成员方法 : 编译看父类|左边|类型,运行看子类|右边|对象

一个有趣的测试题帮助理解
/*
* 做题四大原则:
* 一、继承链:自己没有找父类
* A
* |
* B
* / \
* C D
* 二、 编译看类型、确定方法,运行找对象
*
* 三、就近最优原则
*
* 四、父类引用对子类新增方法不可见
*/
public class Class002_PolyTest {
    public static void main(String[] args) {
        A a1=new A();  //A and D    A and A
        //多态
        A a2=new B();  //A and D    B and A
        B b =new B();  //A and D    B and A     B and B
        C c=new C();
        D d =new D();    
        System.out.println(a1.show(b)); //A and A
        System.out.println(a1.show(c)); //A and A
        System.out.println(a1.show(d)); //A and D
        System.out.println(a2.show(b)); //B and A
        System.out.println(a2.show(c)); //B and A
        System.out.println(a2.show(d)); //A and D
        System.out.println(b.show(b));  //B and B
        System.out.println(b.show(c));  //B and B
        System.out.println(b.show(d));  //A and D
    }

}

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){
        return ("B and A");
    }
}

class C extends B{
}

class D extends B{

注意 :

标准的赋值 : 对应类型的数据赋值给对应类型的变量

int i=1;

多态使用需要配合方法的重写才有意义

四,类型转换

1,标准 : 对应类型的数据赋值给对应类型变量

int i = 1;

2,基本数据类型的类型转换

自动类型提升 : 小--->大

        long l = i;

强制类型转换 : 大--->小,有可能造成损失精度(不精确)-->需要手动进行强转

        int i2 = (int)l;

3,转型 : 引用数据类型的类型转换

父类-->大
子类-->小

3.1当前后类型不一致 :

3.1.1 向上转型 : 小 --> 大 -->多态
            Person p = new Student();

3.1.2 向下转型 : 向下转型对象不变,引用从父类类型转为子类类型,就可以调用子类中所有的成员(子类新增)
            Student s = (Student)p;

3.类型转换异常

  1. java.lang.ClassCastException : 类型转换异常

  1. 使用instanceof运算符在转型之前先判断,再转型,避免类型转换异常的出现

  1. 引用 instanceof 类型 : 判断前面的引用是否是指向后面类型的对象或者子类对象对象,如果是返回true,不是返回false

public class Class001_Cast {
    public static void main(String[] args) {
        Fu f = new Zi();
        //向下转型
        if(f instanceof Zi2){
            Zi2 zi = (Zi2)f;
            zi.test();
        }else if(f instanceof Zi){
            Zi zi = (Zi)f;
            zi.test();
        }


    }
}

class Fu{}

class Zi extends Fu{
    void test(){
        System.out.println("Zi--test");
    }
}

class Zi2 extends Fu{
    void test(){
        System.out.println("Zi2--test");
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值