Java

面向对象2

2022-02-21  本文已影响0人  马佳乐

类的继承

继承的概念

在已有类(基类)的基础上创建新的类(派生类)。新类继承了现有类的属性和方法(不必重新编写代码,实现代码复用),同时又添加了自己的新特性,从而在继承的基础上实现扩充。
在继承关系中,被继承的原有类称为父类、基类或超类
通过继承关系定义出来的新类被称为子类或派生类
子类除了可以继承父类属性和方法外,还可以通过以下方式产生新的成员:

子类的声明

子类的定义格式:

class  子类名  extends  父类名    
    {   子类中新成员的声明   }

父类名:子类的直接父类,是一个已经定义的类,可以来自系统类库或用户自定义类
子类中新成员的声明:子类继承父类所有成员(构造方法除外),但不能直接访问父类的私有成员。
子类对父类可做扩展和特殊化:

能够实现继承的条件:

父类非final(最终类,不能再派生出新的子类);
只有对一个类具有访问控制权限时,才能以此类为基础创建子类。因此,要求父类是public、或父类与子类同包。

子类的继承性访问控制

父类中的成员 private protected public 默认的
同包子类 不可直接访问,但可通过可访问的方法进行访问 可访问,访问权限不变 可访问,访问权限不变 可访问,访问权限不变
不同包子类且父类为public 不可直接访问,但可通过可访问的方法进行访问 可访问,访问权限不变 可访问,访问权限不变 不可直接访问,但可通过可访问的方法进行访问

成员变量的隐藏

在子类中定义与父类中同名的成员变量时,子类就隐藏了继承的成员变量,即子类对象以及子类自己声明定义的方法操作与父类中同名的成员变量。

方法的覆盖

方法的覆盖(方法重写,OverWrite或Override)

方法重写与方法重载(Overload)的区别:

super关键字

子类的构造方法

子类不能继承父类的构造方法。由于子类继承了父类成员,在建立子类的对象时,必须先调用(隐式或显式)父类的构造方法来创建和初始化子类对象的父类成员。

①隐式初始化

如果父类中没有定义任何构造方法,则子类调用父类的默认构造方法
如果父类中定义了包含无参构造方法在内的多个构造方法,且在子类的构造方法中没有显示调用父类的构造方法时,子类就调用父类不带参的构造方法,直到执行完Object的构造方法后才执行子类的构造方法。

②显式初始化

在子类构造方法的第一条语句中通过super()或super(参数列表)调用父类的默认构造方法或带参构造方法
当父类没有提供默认构造方法时,即父类定义的构造方法都是有参数的,则必须在子类的第一条语句通过super(参数列表)完成父类成员的初始化工作。

构造方法的调用顺序:

①在创建子类对象时,首先调用父类的构造方法,初始化子类中的父类成员;
②调用子类的构造方法,初始化子类中的新增数据成员。

多态

在Java中,允许用一个父类类型的变量引用一个子类类型的对象,根据被引用子类对象特征的不同,得到不同的运行结果,这就是多态,继承是实现多态的基础

对象之间的类型转换

对象之间的类型转换分为向上转型和向下转型两种情况。

向上转型

将子类类型的引用赋值给其父类或祖先类类型的引用,赋值操作中包含了隐式的类型转换。

class A{
    …
}
class B extends A{
    …
}
A a;
B b=new B();
a=b;

对象a是子类对象b的上转型对象,上转型对象会丢失原对象的一些属性和功能。上转型对象不能操作子类声明定义的成员变量和方法,即上转型对象不能操作子类新增的方法和成员变量
上转型对象可以操作子类继承的成员变量和隐藏的成员变量,也可以使用子类继承的或重写的方法(多态性)。
将对象的上转型对象再强制转换到一个子类对象,该子类对象又具备了子类的所有属性和功能。
由于向上转型是从一个较具体的类到较抽象的类的转换,所以它总是安全的。

向下转型

将某类类型的引用赋值给其子类类型的引用,赋值操作必须进行显式(强制)的类型转换。向下转型是从较抽象类转换为较具体类,这样的转型通常会出现问题。

class A{
    …
}
class B extends A{
    …
}
A a=new B();
B b=(B)a;

当在程序中执行向下转型操作时,如果父类对象不是子类对象的实例,就会发生ClassCastException异常,所以在执行向下转型之前要使用instanceof运算符来判断父类对象是否为子类对象的实例。
格式
myobject instanceof ExampleClass

final关键字

final关键字可用于修饰类、变量和方法,有“无法改变”或者“最终”的含义。

final修饰类

Java中的类被final关键字修饰后,该类将不可以被继承,即不能派生子类。因此,称被final修饰的类为最终类。

final class A
{
    类体;  
}

final修饰方法

final方法:一个方法被修饰为final,则该方法不能被重写,即不允许子类通过重写隐藏继承的final方法。一般,对于一些比较重要且不希望子类进行更改的方法,可声明为final方法。可防止子类对父类关键方法的错误重写,增加代码的安全性和正确性。

final修饰成员变量

常量:在Java中被final修饰的变量称为常量,只能被赋值一次,即final修饰的变量一旦被赋值,其值不能改变。如果再次对改变量进行赋值,则程序会在编译时出错。

抽象类与接口

抽象类

抽象类:用关键字abstract修饰的类。 (不完善的、应该被继承的类。)
声明格式:

访问权限修饰符  abstract  class 类名{
        类的成员
    }

类的成员
属性成员
方法(构造方法、抽象方法、非抽象方法)

abstract类不能用new运算符创建对象,即抽象类不能创建对象,必须产生其具体子类,由具体子类创建对象

abstract  class A{…}
A a=new A();//错误
abstract  class A{…}
class B extends A{…}
B b=new B();//正确

注意:不允许被创建对象,并不意味着它不允许有构造方法,定义抽象类的构造方法的原则与一般的类完全相同,且在创建子类对象时,该构造方法会被执行。
抽象方法:使用abstract关键字修饰的方法,其格式为:访问权限修饰符 abstract 返回值类型 方法名(参数列表);
抽象方法的特征:

接口

接口是极端的抽象类,即所有方法只有方法的定义,没有方法的实现。

(1)接口的声明

        修饰符    interface  接口名 {
            
            接口体
        }

接口名的命名规范与类相同,接口也可以指定所属的包
修饰符:

(2)接口的实现

(3)接口回调

(4)接口做参数

(5)接口之间的继承

接口与接口之间使用关键字extends实现继承关系
声明格式如下:

public  interface 子接口 extends 父接口1,父接口2,…,父接口n{
    接口体
}

接口支持多继承,即一个接口可以同时继承多个接口,各父级接口之间使用逗号分隔。

(6)接口与抽象类的对比

相同点:

不同点:

内部类

class A{
        class  B{…}
        ……
}

“非静态”内部类

class A{
        class  B{…}
        ……
}
A a=new A();
B b=a.new B();

“静态”内部类

class A{
        static class  B{…}
        ……
}
B b=new B();

局部内部类

定义在方法代码块或局部代码块中的类,也只能在局部代码块中使用

class A{
        void fun(){
    class C{
        void show(){    System.out.println("内部类");  }
    }
    C c=new C();
    c.show();       
         }
}
A a=new A();
a.fun();

匿名内部类

没有名字的内部类,定义匿名内部类的地方往往直接创建该类的一个对象。

class A{
    …
}

A a=new A(){
    …
};

A()后的大括号是匿名类
new是新建匿名类对象
A作为父类,被匿名类继承

上一篇 下一篇

猜你喜欢

热点阅读