JAVA学习笔记04——继承与多态

继承与多态

1.继承
基本语法:
public class 子类名称 extends 父类名称{…}

成员变量访问特点:
在父子类的继承关系当中,如果成员变量重名,则创建子类对象时,访问有两种方式:
直接通过子类对象访问成员变量:
等号左边是谁,就优先用谁,没有则向上找
间接通过成员方法访问成员变量:
方法属于谁,就优先用谁,没有则向上找

成员方法访问特点:
创建的对象是谁,就优先用谁,如果没有则向上找

构造方法访问特点:
1.子类构造方法当中有一个默认隐含的super()调用,所以一定先调用父类构造,再执行子类构造
2.子类构造可以通过super关键字来调用父类构造。
3.super的父类构造调用,必须是子类构造的第一条语句。

super关键字用法:
1.在子类的成员方法中,访问父类的成员变量
2.在子类的成员方法中,访问父类的成员方法
3.在子类的构造方法中,访问父类的构造方法

public class son extends father{
    public son(){
        super();
        System.out.println("子类构造方法");
    }

    public void method(){
        System.out.println(super.num);
        super.method();
    }
}

this关键字用法:
1.在本类的成员方法中,访问本类的成员变量
2.在本类的成员方法中访问另一个成员方法
3.在本类的构造方法中访问另一个构造方法

JAVA继承特征:
1.JAVA是单继承
2.JAVA可以多级继承

2.抽象
抽象方法语法:
public abstract void 方法名();
抽象方法所在的类必须是抽象类
语法:
public abstract class 类名{}

public abstract class Person {
    public abstract void method();
}

抽象类与抽象方法:
1.不能直接创建抽象类对象
2.必须用一个子类继承抽象父类
3.子类必须覆盖重写父类所有抽象方法
4.抽象类中可以有构造方法,是供子类创建对象时,初始化父类成员使用的
5.抽象类中不一定包含抽象方法,但是有抽象方法的类一定是抽象类

public abstract class father {
    public abstract void method();
}
public class son extends father{
    @Override
    public void method() {
        System.out.println("这是一个子类方法");
    }
}

3.接口
一种公共规范的标准,多个类的公共规范。
接口是一种引用数据类型,最重要的是抽象方法
语法:
public interface 接口名称{}

抽象方法:
public abstract 返回值类型 方法名称(参数列表);
注意:
1.接口当中的抽象方法,修饰符必须是两个固定的关键字:public abstract
2.这两个关键字可以省略

使用:
1.接口不能直接使用,必须有一个实现类来实现该接口
public class 实现类名称 implements 接口名称{}
2.接口的实现类必须覆盖重写接口中所有的抽象方法
实现:去掉abstract关键字,加上方法体大括号
3.创建实现类的对象进行使用

public interface MyInterfaceAbstract {
    public abstract void methodAbs();   //接口抽象方法的定义
}

public class MyInterfaceAbstractImpl implements MyInterfaceAbstract{
    @Override
    public void methodAbs() {
        System.out.println("这是一个方法");   //重写接口的抽象方法
    }
}
public class demo01Interface {
    public static void main(String[] args) {
        MyInterfaceAbstractImpl impl=new MyInterfaceAbstractImpl();
        impl.methodAbs();   //创建对象实现抽象方法
    }
}

默认方法
语法:
public default 返回值类型 方法名称(参数列表){}
1.接口的默认方法可以通过接口实现类对象直接调用
2.接口的默认方法可以被接口实现类进行覆盖重写

public interface MyInterfaceDefault {
    public abstract void methodAbs();
//    public abstract void methodAbs2();  //新增抽象方法
    public default void methodDefault(){
        System.out.println("这是新添加的默认方法");
    }
}
public class MyInterfaceDefaultA implements MyInterfaceDefault{
    @Override
    public void methodAbs() {
        System.out.println("实现抽象方法A");
    }
}
public class MyInterfaceDefaultB implements MyInterfaceDefault{
    @Override
    public void methodAbs() {
        System.out.println("实现抽象方法B");
    }

    @Override
    public void methodDefault() {
        System.out.println("这是B重写默认方法");    //覆盖重写
    }
}

public class demo02Interface {
    public static void main(String[] args) {
        MyInterfaceDefaultA a=new MyInterfaceDefaultA();
        a.methodAbs();
        a.methodDefault();  //调用默认方法
        MyInterfaceDefaultB b=new MyInterfaceDefaultB();
        b.methodDefault();  //调用重写默认方法
    }
}

静态方法
语法:
public static 返回值类型 方法名称(参数列表){}
注意事项:
1.不能通过接口实现类的对象来调用接口当中的静态方法
2.通过接口名称直接调用静态方法

public interface MyInterfaceStatic {
    public static void methodStatic(){
        System.out.println("这是一个静态方法");
    }
}
public class demo03Interface {
    public static void main(String[] args) {
        MyInterfaceStatic.methodStatic();
    }
}

私有方法
解决多个静态方法之间重复代码
普通私有方法:
private 返回值类型 方法名称(参数列表){}
静态私有方法:
private static 返回值类型 方法名称(参数列表){}

public interface MyInterfacePrivateA {
    public default void MethodDefault1(){
        System.out.println("这是默认方法1");
        methodCommon();
    }
    public default void MethodDefault2(){
        System.out.println("这是默认方法2");
        methodCommon();
    }
    private void methodCommon(){
        System.out.println("默认方法");
    }
}

接口的常量
接口当中也可以定义成员变量,但是必须使用public static final三个关键字进行修饰
从效果上看,这其实就是接口的常量
语法:
public static final 数据类型 常量名称=数据值;
注意:
1.接口当中的常量可以省略public static final关键字
2.接口当中的常量必须赋值
3.接口中常量名称使用完全大写,用下划线分隔

使用:
接口名称.常量名称

public interface MyInterfaceConst {
    public static final int NUM_My_Class=10;
}

多个接口
语法:
public class 类名称 implements 接口1,接口2{}
如果多个接口中存在重名的抽象方法,重写一次即可
如果实现类没有重写所有抽象方法,则实现类是一个抽象类
如果多个接口中存在重复的默认方法,那么实现类一定要对冲突的默认方法进行重写
一个类如果父类与接口当中的方法重名冲突,那么优先父类的方法

接口多继承
1.类与类之间单继承,直接父类只有一个
2.类与接口之间是多实现的,一个雷可以实现多个接口
3.接口与接口之间多继承
注意:
1.多个父接口当中的抽象方法如果重复,并无问题
2.多个父接口当中的默认方法如果重复,那么子接口必须进行默认方法的覆盖重写,并且必须带default关键字

4.多态
语法:
父类名称 对象名=new 子类名称();
接口名称 对象名=new 实现类名称();

public class Father {
    public void method(){
        System.out.println("父类方法");
    }
}
public class Son extends Father{
    public void method(){
        System.out.println("子类方法");
    }
}
public class Demo01Multi {
    public static void main(String[] args) {
        Father obj=new Son();
        obj.method();   //子类方法
    }
}

访问成员变量的两种方式:
1.直接通过对象名访问成员变量:等号左边是谁优先用谁,没有则向上查找
2.间接通过成员方法访问成员变量:该方法属于谁优先用谁,没有则向上查找

成员方法访问的方式:
new的哪个类名,就有限用谁,没有则向上查找
成员变量:编译看左,运行看左
成员方法:编译看左,运行看右

如何才能知道一个父类的引用对象本来是什么子类?
语法:
对象 instanceof 类名称
这将会得到一个boolean值结果,也就是判断前面的对象能不能当做后面类型的实例

5.final关键字
1.修饰类
当前这个类不能有任何子类
public final class 类名称(参数列表){}
2.修饰方法
当前这个方法不能被覆盖重写
public final 返回值 方法名称(参数列表){}
3.修饰局部变量
变量不可改变
final 变量类型 变量名称=值;
对于基本类型来说,不可变说的是变量当中的数据不可改变
对于引用类型来说,不可变说的是变量当中的地址值不可改变
4.修饰成员变量
对于成员变量来说,如果使用final关键字修饰,那么这个变量不可变
注意:
1.由于成员变量有默认值,所以用了final之后必须手动赋值
2.对于final的成员变量,要么直接赋值,要么通过构造方法赋值

6.权限修饰符

publicprotecteddefaultprivate
同一个类yesyesyesyes
同一个包yesyesyesno
不同包子类yesyesnono
不同包非子类yesnonono

7.内部类
1.成员内部类
修饰符 class 类名称{
修饰符 class 内部类名称{}
}
注意:
内部类使用外部类随意访问;外用内一定要有内部类对象

public class Body {
    public class Heart{
        public void beat(){
            System.out.println("内部类方法");
            method();   //调用外部类方法
        }
    }
    public void method(){
        Heart heart=new Heart();    //调用内部类方法
        System.out.println("外部类方法");
    }
}

使用:
1.间接方式:在外部类的方法当中使用内部类,main只调用外部类方法
2.直接方式:
类名称 对象名=new 类名称();
外部类名称.内部类名称 对象名=new 外部类型名称

public class Body {
    public class Heart{
        public void beat(){
            System.out.println("内部类方法");
            method();   //调用外部类方法
        }
    }
    public void method(){
        Heart heart=new Heart();    //调用内部类方法
        System.out.println("外部类方法");
    }
}
public class demo01 {
    public static void main(String[] args) {
        Body body=new Body();
        body.method();
        Body.Heart heart=new Body().new Heart();
        heart.beat();
    }
}

同名变量访问:
外部类名称.this.成员变量

public class Outer {
    int num=10;
    public class Inner{
        int num=20;
        public void method(){
            int num=30;
            System.out.println(num);    //30
            System.out.println(this.num);   //20
            System.out.println(Outer.this.num); //10
        }
    }
}

2.局部内部类
如果一个类是定义在一个方法内部的,那么这就是一个局部内部类
只有当前所属的方法才能使用它,出了这个方法外面就不能用了
语法:
修饰符 class 外部类名称{
修饰符 返回值类型 外部类方法名称(参数列表){
class 局部内部类名称{
}
}
}

public class Outer {
    public void methodOuter(){
        class Inner{    //局部内部类
            int num=10;
            public void methodInner(){
                System.out.println(num);
            }
        }
        Inner inner=new Inner();
        inner.methodInner();
    }
}

定义一个类的时候,权限修饰符规则:
1.外部类:public/default
2.成员内部类:public/protected/default/private
3.局部内部类:什么都不能写

匿名内部类:
接口名称 对象名=new 接口名称{
//覆盖重写所有抽象方法
}

public class DemoMain {
    public static void main(String[] args) {
        MyInterface obj=new MyInterface() {
            @Override
            public void method() {
                System.out.println("匿名内部类实现方法");
            }
        };
        obj.method();
        new MyInterface(){
            public void method(){
                System.out.println("匿名内部类实现方法2");
            }
        }.method();
    }
}

注意事项:
1.匿名内部类在创建对象的时候只能使用唯一一次,如果希望多次创建对象,而且类的内容一样的话,就必须使用单独定义的实现类了。
2.匿名对象,在调用方法的时候只能调用唯一一次,如果希望同一个对象调用多次方法,就必须给对象起个名字。
3.匿名内部类省略了实现类/子类名称,但是匿名对象是省略了对象名称

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值