继承,多态,final,常量,抽象类,接口

1,继承

(1)继承的定义

Java提供了了一个关键词extends,用这个关键字,可以让一个类与另一个类建立起父子关系

public class B extends A{

}

A类称为父类(基类或超类)  B类称为子类(派生类)

继承的特点:子类能继承父类的非私有成员(成员变量,成员方法)

继承后对象的创建:子类的对象是由子类,父类共同完成的

带继承的类,java会用类和其父类,这多张设计图一起来创建类的对象

对象能直接访问什么成员,是由子父类这多张设计图共同决定的,这多张设计图对外暴露了什么成员,对象就可以访问什么成员

继承的好处:减少了重复代码的缩写,提高了代码的复用性

(2)极限修饰符

(3)单继承

1,java是单继承的,一个类只能继承一个父类,java中的类不支持多继承,但是支持多层继承

2,Object类是java中所有类的祖宗

(4)方法重写

方法重写:当子类觉得父类的某个方法不好用时,或者无法满足自己的需求时,子类可以重写一个方法名称,参数列表一样的方法,去覆盖父类的这个方法,这就是方法重写

注意:重写后,方法的访问,java就会遵循就近原则

方法重写的注意事项:

1)重写小技巧:使用Override注解,他可以指定java编译器,检查我们的方法重写的格式是否正确,代码可读性也会更好

2)子类重写父类方法时,访问权限必须大于或等于父类该方法的权限(public>protected>缺省)

3)重写的方法返回值类型,必须与被重写方法的返回值类型一样,或者范围更小

4)私有方法,静态方法不能被重写,如果重写会报错的

方法重写在开发中的常见应用场景

子类重写Object类的toString()方法,以便返回对象的内容

在子类方法中访问其他成员(成员变量,成员方法),是依照就近原则的

1)先在子类局部范围找

2)然后子类成员范围找

3)然后父类成员范围找,如果父类访范围还没有找到则报错

如果子父类中,出现了重名的成员,会优先使用子类的,如果此时一定要在子类中使用父类,则可以使用super关键字,指定访问父类的成员:super。父类成员变量/父类成员方法

(5)子类构造器

子类的全部构造器,都会先调用父类的构造器,再执行自己

子类构造器调用父类构造器:

默认情况下,子类全部构造器的第一行代码都是super()(写不写都有),它会调用父类的无参数构造器

如果父类没有无参数构造器,则我们必须在子类构造器的第一行手写super(......),指定去调用父类的有参数构造器

this(...)调用兄弟构造器

(1)任意类的构造器中,是可以通过this(...)去调用该类的其他构造器的


    public Student1(String name,int age){
        //this.name=name;
        //this.age=age;
        //this.schoolName="北京大学";
        this(name,age,"北京大学");

    }

    public Student1(String name, int age, String schoolName) {
        this.name = name;
        this.age = age;
        this.schoolName = schoolName;
    }

this(...)不可以和super()同时使用,二者均需放在第一行

2,多态

多态是在继承/实现情况下的一种现象,表现为:对象多态,行为多态

多态的具体代码体现

People p1=new Teacher();
p1.run();//识别技巧,编译看左边,运行看右边
System.out.println(p1.name);//对于变量,编译看左边,运行看左边

People p2=new Student();
p2.run();//识别技巧,编译看左边,运行看右边
System.out.println(p2.name);

多态的前提:

有继承/实现关系;存在父类引用子类对象;存在方法重写

注意事项:多态是对象,行为的多态,java中的属性(成员变量)不谈多态

多态的好处

(1)在多态形势下,右边对象是解耦合的,更利于扩展和维护

(2)定义方法时,使用父类类型的形象,可以接收一切子类对象,扩展性更强,更便利

public static void main(String[] args) {
        People p1=new Teacher();
        p1.run();

        Student s=new Student();
        go(s);

        Teacher t=new Teacher();
        go(t);

    }
    public static void go(People p){

    }

多态的问题:多态下不能使用子类的独有功能

解决方法

(1)类型转换

自动类型转换:父类 变量名=new 子类(); 例如:People p=new Teacher();

强制类型转换:子类 变量名=(子类)父类变量; 例如:Teacher t=(Teacher)p;

 Student s1=(Student) p1;//强制类型转换
        s1.test();

强制类型转换的注意事项:

(1)存在继承/实现关系就可以在编译阶段进行强制类型转换,编译阶段不会报错

(2)运行时,如果发现对象的真实类型与强制转换后的类型不同,就会报类型转换异常(ClassCastException)的错误出来

强转前,java建议使用instanceof关键字,判断当前对象的真实性,再进行强转

p instanceof Student

if (p1 instanceof Student){
            Student s2=(Student) p1;
            s2.test();
        }else{
            Teacher t2=(Teacher) p1;
            t2.teach();
        }

2,final

final

final关键字是最终的意思,可以修饰(类,方法,变量)

修饰类:该类被称为最终类,特点是不能被继承了

修饰方法:该方法被称为最终方法,特点是不能被重写了

修饰变量:该变量只能被赋值一次

final修饰变量的注意

final修饰基本类型的变量,变量存储的数据不能被改变

final修饰引用类型的变量,变量存储的地址不能被改变,但地址所指向对象的内容是可以被改变的

常量

使用了static final修饰的成员变量就被称为常量

作用:通常用于记录系统的配置信息

使用常量记录系统配置信息的优势、执行原理

代码可读性更好,可维护性也更好

程序编译后,常量会被“宏替换”︰出现常量的地方全部会被替换成其记住的字面量,这样可以保证使用常量和直接用字面量的性能是一样的


3,抽象类

在Java中有一个关键字叫: abstract,它就是抽象的意思,可以用它修饰类、成员方法

abstract修饰类,这个类就是抽象类;修饰方法,这个方法就是抽象方法

修饰符abstract class类名{
        修饰符 abstract 返回值类型 方法名称(形参列表)
}
public abstract class A{
    //抽象方法:必须abstract修饰,只有方法签名,不能有方法体
    public abstract void test();
}

抽象类的注意事项和特点:

抽象类中可以不写抽象方法,但是抽象方法的类一定是抽象类

类有的成员(成员变量,方法,构造器)抽象类都具备

抽象类不能创建对象,仅作为一种特殊的父亲,让子类继承并实现

一个类继承抽象类,必须重写完抽象类的全部抽象方法,否则这个类也必需定义成抽象类

抽象类的场景和好处:

父类知道每个子类都要做某个行为,但每个子类要做的情况不一样,父类就定义成抽象方法,交给子类去重写实现,我们设计这样的抽象类,就是为了更好的支持多态

模板设计模式解决了什么问题:

解决方法中存在重复代码的问题

写法:

(1)定义一个抽象类

(2)在里面定义两个方法

        一个是模板方法:把相同代码放里面去

        一个是抽象方法:具体实现交给子类去完成

模板方法建议用final修饰

4,接口

1,认识接口

java提供了一个关键字interface,用这个关键字我们可以定义出一个特殊的结构:接口

public interface 接口名{
    //成员变量(常量)
    //成员方法(抽象方法)
}

注意:接口不能创建对象;接口是用来被类实现(implements)的,实现接口的类称为实现类

修饰符 class 实现类 implements 接口1,接口2,接口3,...{
}

一个类可以实现多个接口(接口可以理解成干爹),实现类实现多个接口,必须重写完全部接口的全部抽象方法,否则实现类需要定义为抽象类

2,接口的好处

(1)弥补了类单继承的不足,一个类同时可以实现多个接口

(2)让程序可以面向接口编程,这样程序员就可以灵活方便的切换各种业务实现

        Singer s=new A();
        s.sing();

        Driver d=new A();
        d.drive();
        Singer s=new A();
        s.sing();

        Driver d=new B();
        d.drive();

3,接口中新定义的3种方法

public interface A {
    //默认方法:必须使用default修饰,默认会被public修饰
    //实例方法:对象的方法,必须用实现类的对象来访问
    public default void test1(){
        System.out.println("===默认方法===");
        test2();
    }

    //私有方法:必须要用private修饰(JDK9才开始支持)
    //实例方法:对象的方法
    private void test2(){
        System.out.println("===私有方法===");
    }

    //静态方法:必须使用static修饰,会默认用public修饰
    public static void test3(){
        System.out.println("===静态方法===");
    }
}
//认识JDK8中接口新增的3种方法形式
        B b = new B();
        b.test1();
        //b.test2();
        A.test3();

为神马要新增这些方法

增强了接口的能力,更利于项目的扩展和维护

接口的多继承:一个接口可以同时继承多个接口

作用:便于实验类去实现

interface D extends C,B,A{

}

3,使用接口的一些注意事项

(1)一个接口继承多个接口,如果多个接口中存在方法签名冲突,则此时不支持多继承

interface I{
        void test1();
}
interface J{
        String test1();
}
interface K extends I,J{
        //报错
}

(2)一个类实现多个接口,如果多个接口中存在方法签名冲突,则此时不支持多实现

 class E implements I,J{
        //报错
    }

(3)一个类继承了父类,有同时实现了接口,父类中和接口中有同名的默认方法,实现类会优先用父亲的

(4)一个类实现了多个接口,多个接口中存在同名的默认方法,可以不冲突,这个类重写该方法即可

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值