09-面向对象--封装+继承

一、封装

1、封装:隐藏对象的属性和实现细节,仅对外提供公共的访问方式(将类的某些信息隐藏在类内部,不允许外部程序直接访问,而是通过该类提供的方法来实现对隐藏信息的操作和访问)

2、封装最常见最基本的动作:创建对象、调用成员、指挥对象做事情

3、规范:类中定义的成员变量通常都会被私有化(private),对外提供对应的set、get方法(赋值、获取),set、get方法是为了对数据进行可控(可以在方法中对给定的数据进行逻辑判断)。set方法返回值类型是void,get方法返回值类型和属性类型相同

4、封装的实现步骤:

(1)修改属性的可见性 -- 设为private

(2)创建set、get方法 -- 用于属性的读写

(3)在set、get方法中加入属性控制语句 -- 对属性值的合法性进行判断

注意:不使用set、get方法,而是使用一般方法给属性赋值是可以的,但不标准

5、封装的好处:

(1)将变化隔离(隐藏类的实例细节,方便修改和实现) -- 类内部的结构可以自由修改

(2)便于使用(只能通过规定的方法访问数据) -- 隐藏信息好实现细节,有些数据不提供方法就访问不了

(3)提高重用性

(4)提高安全性 -- 可以对成员进行更精确的控制(加if判断)

6、一旦有属性,几乎都隐藏。对外提供方法的目的是可以对属性进行控制

7、封装的原则:

(1)将不需要对外提供的内容都隐藏起来

(2)把属性都隐藏,提供公共方法对其访问 -- 通常的表现形式。只要是类中的成员,不需要对外提供的,都可以隐藏(方法不是一定要对外提供)

8、私有(private)是封装的一种体现,不私有一样能封装

9、Java中最小的封装体是函数。类和框架都是封装体 -- 只要是内部隐藏起来的都是封装,这样不需要了解细节,便于使用

二、继承

1、何时定义继承?

    当类与类之间存在着所属关系时,就定义继承。 eg:xxx is a yyy --> xxx extends yyy

2、继承的好处和弊端:

好处:

(1)提高代码的复用性

(2)让类与类之间产生关系,为第三个特征多态提供前提(没继承,没多态)

弊端:打破封装性

3、父类是在不断向上抽取的过程中产生的

4、java中支持单继承,不直接支持多继承(有多个直接父类)。因为多个父类中有相同成员,会产生调用的不确定性。但java对C++中的多继承机制进行了改良,通过“多实现”的方式来体现

5、java支持多层继承/多重继承(C继承B,B继承A ...),也就是继承体系。

     使用继承体系时,(1)要查看该体系中的最顶层类,了解该体系中最共性、最基本的功能(2)使用时,创建该体系中最子类的对象,因为最子类不仅有其父类的内容,还有自己特有的内容

6、判断是否是继承,看是否有extends关键字,而不是看类名

7、this代表一个本类对象的引用,super代表一个父类空间子类加载进内存时,因为extends,在方法区中,子类方法就持有了super引用,指向父类空间,所以子类可以获取父类中的内容

注:super不代表父类对象,因为内存中自始至终只有一个子类对象,并没有父类对象,所以super不能代表父类对象

(当本类的成员变量和局部变量同名时,用this来区分;当子父类中的成员变量同名时,用super区分父类)

8、自己本空间中有,就不去外面找 -- 子类中有就不找父类,局部中有就不找成员

9、子父类中成员变量内存分析:

(1)子类加载时,父类先于子类加载进内存

(2)父类没有对象,随着子类对象的创建,父类的成员变量存在于子类的对象中(两个数据间只要有关系,他们就在一个对象中分空间存储

(3)父类的成员变量在子类中持有一个super引用,子类的成员变量在子类中持有一个this引用

10、说明:

(1)父类中有的成员变量,子类一般直接拿来用,不用再重新定义一个

(2)通常情况下,成员变量都是私有的,对外提供set、get方法。子类直接调用set、get方法完成对父类的访问

(3)子类对于父类私有的成员(成员变量和成员函数),也继承过来了,存储在子类对象中,用数字标识来标识其私有权限。但外界不能直接访问,只能通过内部间接的方式来访问

(4)变量不涉及覆盖

11、子父类中成员函数相同,会运行子类的函数,这种现象叫做覆盖

12、函数的两个特性:

(1)重载:同一个类中,函数名相同,参数列表不同,与返回值类型无关,与权限无关

(2)覆盖:子父类中,函数声明(包括返回值类型、方法名、参数列表)完全一致,权限子大父小(大盖小)异常子小父大。覆盖也叫重写、覆写

注:子父类中同名的成员函数可以在子父类中同时存在,是因为他们都有所属,一个属于父类,一个属于子类

       方法重载是一个类的多态性表现,而方法覆盖是子父类的多态性表现

13、覆盖注意事项:

(1)子类方法覆盖父类方法时,子类成员函数的权限大于等于父类成员函数的权限

注:如果父类的成员函数私有的,子类与其一模一样的成员函数不叫覆盖。因为覆盖是子类不用的时候,父类可以使用,而私有的外面都不知道,无法使用

(2)静态只能覆盖静态,或被静态覆盖。 即两个方法中,只要有一个是static,另一个也必须是static,否则报错

14、覆盖的应用:

(1)通过一个类继承原来的类的方式进行代码升级,升级后还是原来的类的一种,只是多了新功能

(2)当对一个类进行子类的扩展时,子类需要保留父类的功能声明(函数声明),定义子类中该功能的特有内容,此时使用覆盖操作完成

15、继承可以基本的提高程序的扩展性

16、子类在构造对象时,必须访问父类的构造函数。所以,子类构造函数第一行,有一个默认的隐式语句:super();,用来调用父类的空参构造函数。如果不想用空参的,可以用super(参数列表)指定

注:子类中所有的构造函数,默认都会访问父类中空参数的构造函数(默认的,不写也有)。因为子类继承了父类,获取到父类中的内容。在使用父类内容之前要先看看父类是如何对自己的内容进行初始化的。如果要指定访问父类哪个构造函数,需要显示指定,用super(参数列表),且必须放在子类构造函数的第一行(父类的初始化动作要先完成)

17、关于子父类的构造函数:

(1)构造函数不能覆盖,因为函数名不同

(2)构造函数没有继承过来。所以换了另一种方式来访问,即在初始化时,可以通过super()访问父类的构造函数

18、如果子类的构造函数出现了重载,且其中的某些构造函数中调用了this(参数列表);,此时this()要放在子类调用this()方法的构造函数的第一行,且该构造函数中不写super()。但总会有一个构造函数执行super(参数列表)进行父类的初始化

注:this()和super()都只能定义在第一行,但只能有一个

eg:

class Zi extends Fu {
    Zi( ) {
        //super(); //至少有一个构造函数执行super()访问父类的构造函数,进行父类初始化
        xxxxxx;
    }
    Zi( int x ) {
        this();    //使用this()调用本类构造函数。此构造函数中没有super()
        xxxxxx;
    }
}//super(); //至少有一个构造函数执行super()访问父类的构造函数,进行父类初始化
        xxxxxx;
    }
    Zi( int x ) {
        this();    //使用this()调用本类构造函数。此构造函数中没有super()
        xxxxxx;
    }
}

19、在进行一个类的编写时,它里面都有一个隐式的构造函数,构造函数中有一句隐式的super()和return

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值