精华内容
下载资源
问答
  • 面向对象三个基本特征

    千次阅读 2013-03-29 09:00:41
    面向对象三个基本特征是:封装、继承、多态。 封装 封装最好理解了。封装是面向对象特征之一,是对象和类概念的主要特性。 封装,也就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的...

    面向对象的三个基本特征是:封装、继承、多态。

    o_OOBase.gif

    封装

    封装最好理解了。封装是面向对象的特征之一,是对象和类概念的主要特性。

    封装,也就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。

    继承

    面向对象编程 (OOP) 语言的一个主要功能就是“继承”。继承是指这样一种能力:它可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。

    通过继承创建的新类称为“子类”或“派生类”。

    被继承的类称为“基类”、“父类”或“超类”。

    继承的过程,就是从一般到特殊的过程。

    要实现继承,可以通过“继承”(Inheritance)和“组合”(Composition)来实现。

    在某些 OOP 语言中,一个子类可以继承多个基类。但是一般情况下,一个子类只能有一个基类,要实现多重继承,可以通过多级继承来实现。

     

    继承概念的实现方式有三类:实现继承、接口继承和可视继承。

    Ø         实现继承是指使用基类的属性和方法而无需额外编码的能力;

    Ø         接口继承是指仅使用属性和方法的名称、但是子类必须提供实现的能力;

    Ø         可视继承是指子窗体(类)使用基窗体(类)的外观和实现代码的能力。

    在考虑使用继承时,有一点需要注意,那就是两个类之间的关系应该是“属于”关系。例如,Employee 是一个人,Manager 也是一个人,因此这两个类都可以继承 Person 类。但是 Leg 类却不能继承 Person 类,因为腿并不是一个人。

    抽象类仅定义将由子类创建的一般属性和方法,创建抽象类时,请使用关键字 Interface 而不是 Class。

    OO开发范式大致为:划分对象→抽象类→将类组织成为层次化结构(继承和合成) →用类与实例进行设计和实现几个阶段。

     

    多态

    多态性(polymorphisn)是允许你将父对象设置成为和一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。简单的说,就是一句话:允许将子类类型的指针赋值给父类类型的指针。

    实现多态,有二种方式,覆盖,重载。

    覆盖,是指子类重新定义父类的虚函数的做法。

    重载,是指允许存在多个同名函数,而这些函数的参数表不同(或许参数个数不同,或许参数类型不同,或许两者都不同)。

    其实,重载的概念并不属于“面向对象编程”,重载的实现是:编译器根据函数不同的参数表,对同名函数的名称做修饰,然后这些同名函数就成了不同的函数(至少对于编译器来说是这样的)。如,有两个同名函数:function func(p:integer):integer;和function func(p:string):integer;。那么编译器做过修饰后的函数名称可能是这样的:int_func、str_func。对于这两个函数的调用,在编译器间就已经确定了,是静态的(记住:是静态)。也就是说,它们的地址在编译期就绑定了(早绑定),因此,重载和多态无关!真正和多态相关的是“覆盖”。当子类重新定义了父类的虚函数后,父类指针根据赋给它的不同的子类指针,动态(记住:是动态!)的调用属于子类的该函数,这样的函数调用在编译期间是无法确定的(调用的子类的虚函数的地址无法给出)。因此,这样的函数地址是在运行期绑定的(晚邦定)。结论就是:重载只是一种语言特性,与多态无关,与面向对象也无关!引用一句Bruce Eckel的话:“不要犯傻,如果它不是晚邦定,它就不是多态。”

    那么,多态的作用是什么呢?我们知道,封装可以隐藏实现细节,使得代码模块化;继承可以扩展已存在的代码模块(类);它们的目的都是为了——代码重用。而多态则是为了实现另一个目的——接口重用!多态的作用,就是为了类在继承和派生的时候,保证使用“家谱”中任一类的实例的某一属性时的正确调用。

     

    概念讲解

    泛化(Generalization)

    o_Generalization.gif

    图表 1 泛化

    在上图中,空心的三角表示继承关系(类继承),在UML的术语中,这种关系被称为泛化(Generalization)。Person(人)是基类,Teacher(教师)、Student(学生)、Guest(来宾)是子类。

    若在逻辑上B是A的“一种”,并且A的所有功能和属性对B而言都有意义,则允许B继承A的功能和属性。

    例如,教师是人,Teacher 是Person的“一种”(a kind of )。那么类Teacher可以从类Person派生(继承)。

    如果A是基类,B是A的派生类,那么B将继承A的数据和函数。

    如果类A和类B毫不相关,不可以为了使B的功能更多些而让B继承A的功能和属性。

    若在逻辑上B是A的“一种”(a kind of ),则允许B继承A的功能和属性。

     

    聚合(组合)

    o_aggregationBase.gif

    图表 2 组合

    若在逻辑上A是B的“一部分”(a part of),则不允许B从A派生,而是要用A和其它东西组合出B。

    例如,眼(Eye)、鼻(Nose)、口(Mouth)、耳(Ear)是头(Head)的一部分,所以类Head应该由类Eye、Nose、Mouth、Ear组合而成,不是派生(继承)而成。

     

    聚合的类型分为无、共享(聚合)、复合(组合)三类。

     

    聚合(aggregation)

     

    o_aggregation.gif

    图表 3 共享

    上面图中,有一个菱形(空心)表示聚合(aggregation)(聚合类型为共享),聚合的意义表示has-a关系。聚合是一种相对松散的关系,聚合类B不需要对被聚合的类A负责。

     

    组合(composition)

    o_composition.gif

    图表 4 复合

    这幅图与上面的唯一区别是菱形为实心的,它代表了一种更为坚固的关系——组合(composition)(聚合类型为复合)。组合表示的关系也是has-a,不过在这里,A的生命期受B控制。即A会随着B的创建而创建,随B的消亡而消亡。

     

    依赖(Dependency)

    o_Dependency.gif

    图表 5 依赖

    这里B与A的关系只是一种依赖(Dependency)关系,这种关系表明,如果类A被修改,那么类B会受到影响。

    展开全文
  • C++面向对象三个基本特征

    千次阅读 2019-09-19 20:00:38
    封装是面向对象特征之一,是对象和类概念的主要特性. 简单的说,一类就是一封装了数据以及操作这些数据的代码的逻辑实体。在一对象内部,某些代码或某些数据可以是私有的,不能被外界访问。通过这种方式,...

    一、三大特征
    封装,继承,多态

    二、封装
    所谓封装就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏.封装是面向对象的特征之一,是对象和类概念的主要特性. 简单的说,一个类就是一个封装了数据以及操作这些数据的代码的逻辑实体。在一个对象内部,某些代码或某些数据可以是私有的,不能被外界访问。通过这种方式,对象对内部数据提供了不同级别的保护,以防止程序中无关的部分意外的改变或错误的使用了对象的私有部分。

    三、继承
    所谓继承就是指可以让某个类型的对象获得另一个类型的对象的属性的方法。它支持按级分类的概念。继承是指这样一种能力:它可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展. 通过继承创建的新类称为“子类”或“派生类”,被继承的类称为“基类”、“父类”或“超类”。继承的过程,就是从一般到特殊的过程。要实现继承,可以通过“继承”(Inheritance)和“组合”(Composition)来实现.继承概念的实现方式有二类:实现继承与接口继承.实现继承是指直接使用基类的属性和方法而无需额外编码的能力;接口继承是指仅使用属性和方法的名称、但是子类必须提供实现的能力。

    四、多态
    所谓多态就是允许你将父对象设置成为和一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。简单的说,就是一句话:允许将子类类型的指针赋值给父类类型的指针。
    多态的三个条件:有继承,有虚函数重写,有父类指针指向子类对象。

    展开全文
  • Java面向对象编程特征 - 封装

    千次阅读 多人点赞 2020-03-25 20:45:49
    本文关键字:Java、面向对象特征、封装。封装是面向对象编程中的特征之一,在对封装性进行解释时我们有必要先了解一些面向对象的思想,以及相关的概念。

    写在前面:博主是一只经过实战开发历练后投身培训事业的“小山猪”,昵称取自动画片《狮子王》中的“彭彭”,总是以乐观、积极的心态对待周边的事物。本人的技术路线从Java全栈工程师一路奔向大数据开发、数据挖掘领域,如今终有小成,愿将昔日所获与大家交流一二,希望对学习路上的你有所助益。同时,博主也想通过此次尝试打造一个完善的技术图书馆,任何与文章技术点有关的异常、错误、注意事项均会在末尾列出,欢迎大家通过各种方式提供素材。

    • 对于文章中出现的任何错误请大家批评指出,一定及时修改。
    • 有任何想要讨论和学习的问题可联系我:zhuyc@vip.163.com。
    • 发布文章的风格因专栏而异,均自成体系,不足之处请大家指正。

    Java面向对象编程三大特征 - 封装

    本文关键字:Java、面向对象、三大特征、封装


    封装是面向对象编程中的三大特征之一,在对封装性进行解释时我们有必要先了解一些面向对象的思想,以及相关的概念。当我们想要去描述一系列的关系时我们要用到的最基本结构就是类,其中存在着成员变量和方法,用于记录属性和表达行为,相关知识请进传送门:Java中的基本操作单元 - 类和对象

    一、名词解读

    为了解释封装的概念和作用,需要先来了解一下几个相关的概念,这有助于我们接下来的理解。

    1. 权限修饰符

    当我们在一个类中定义成员变量时,会指定一个变量的类型,除此之外,还会有修饰符的部分,在此给出定义成员变量的规范格式:

    // 定义变量
    [修饰符] 变量类型 变量名称;
    [修饰符] 变量类型 变量名称 = 初始值;
    

    修饰符起到的作用从字面就可以解释,起到一个修饰和限定的作用,可以使用在成员变量之前的修饰符可以是:publicprotectedprivate、final、static。
    修饰符与修饰符之间的顺序没有强制要求,其中public、protected、private被称为权限修饰符,可以用来限定类的属性和方法的访问权限,指明在哪些包的哪些类中能够调用到这些属性或方法,是一种一定会存在的修饰符。需要注意的是,这三个单词不能同时出现,当这三个单词都不出现的时候会被认为是默认访问权限,所以权限修饰符一共有四种:private、默认、protected、public。

    2. 权限对应关系表

    • private:私有权限,只能在定义的类中访问,在其他类中创建的实例均无法访问
    • 默认:同包可访问权限,在没有声明权限修饰符时为默认权限,允许在同包的其他类访问
    • protected:受保护权限,允许有继承关系的子类访问
    • public:公共权限,允许任何类访问

    3. 属性访问

    由于权限修饰符在封装特性中的作用只是实现封装性的一种途径,所以在这里只演示private与public的作用,权限修饰符的其他作用将在后续的文章中继续介绍。

    src
    └──edu
        └──sandtower
            └──bean
                │    Person.java
            └──test
                │    Test.java
    

    以上为实体类与测试类所在的目录结构,Person实体类所在包:edu.sandtower.bean,Test测试类所在包:edu.sandtower.test,相应代码如下:

    package edu.sandtower.bean;
    
    public class Person{
        // 声明公开属性
        public String name;
        // 声明私有属性
        private double money;
    }
    
    package edu.sandtower.test;
    
    import edu.sandtower.bean.Person;
    
    public class Test{
        public static void main(String[] args){
            // 在test包中的Test类中创建Person实例
            Person person = new Person();
            person.name = "小张";// 编译通过,可以访问name属性
            person.money = 500.0;// 编译失败,无法访问money属性
        }
    }
    

    从上面的例子可以看出,虽然依然是使用Person自己的实例在进行属性的调用,但是我们是在另外一个包中的类发生的调用,所以是不能够访问到private修饰的属性的,在刚开始学习时一定要注意区分。

    二、概念阐释

    1. 封装有什么用

    通过使用权限修饰符,我们可以限定类的成员的被访问权限,那为什么要这样做呢?在很多场景下,我们需要确保我们对属性值的操作均是有效操作,不能违背某些规则。
    比如,我们定义了一个Person类,具有name和money两个属性,在买东西时需要扣掉相应的金额,原始写法如下:

    public class Person{
        public String name;
        public double money;
    }
    
    public class Test{
        public static void main(String[] args){
            Person person = new Person();
            person.money = 500;// 初始金额500元
            System.out.println("购买一张桌子,花费200元");
            person.money -= 200;
            System.out.println("购买二手PSP,花费350元");
            person.money -= 350;
            System.out.println("目前余额为:" + person.money);// -50
        }
    }
    

    可以看到,经过代码操作以后可能会导致money的属性为负。看官甲:你自己不加判断赖代码?没错,这个问题我们可以增加判断代码来解决,由于这个操作是对money属性值的操作,我们将它封装成一个方法写在实体类中,于是有了改进之后的代码:

    public class Person{
        public String name;
        public double money;
    
        // 定义一个方法,用于设置money属性的值
        public void setMoney(double money){
            if(money >= 0){
                this.money = money;
            }
        }
    }
    
    public class Test{
        public static void main(String[] args){
            Person person = new Person();
            person.money = 500;// 初始金额500元
            System.out.println("购买一张桌子,花费200元");
            person.setMoney(person.money - 200);
            System.out.println("购买二手PSP,花费350元");
            person.setMoney(person.money - 350);
            System.out.println("目前余额为:" + person.money);// 300
        }
    }
    

    经过上面的改进,我们可以确保money的值不为负数,同时可以看到,当在实体类中定义方法后,使用者需要修改属性值时直接调用方法就可以保证不出问题。但是由于属性值依然可以被直接访问,还不能保证万无一失,于是我们利用权限修饰符使得变量不能被直接访问,同时需要定义一个能够取得属性值的方法。

    public class Person{
        public String name;
        // 声明money属性为private权限
        private double money;
    
        // 定义一个方法,用于设置money属性的值
        public void setMoney(double money){
            if(money >= 0){
                this.money = money;
            }
        }
        // 定义一个方法,用于获取money属性的值
        public double getMoney(){
            return this.money;
        }
    }
    
    public class Test{
        public static void main(String[] args){
            Person person = new Person();
            person.money = 500;// 初始金额500元
            System.out.println("购买一张桌子,花费200元");
            person.setMoney(person.getMoney() - 200);
            System.out.println("购买二手PSP,花费350元");
            person.setMoney(person.getMoney() - 300);
            System.out.println("目前余额为:" + person.getMoney());// 300
        }
    }
    

    通过以上的案例,我们可以看到进行封装有以下几个作用:

    • 防止类的属性被外部代码随意的修改和访问,保证数据的完备性
    • 将对属性的操作转换为方法,更加灵活和安全
    • 使用封装可以隐藏实现的细节:使用者只需要作用,不需要知道过程
    • 在类的定义结构中修改,提高了代码的可维护性,同时又可以不影响外部的使用
    • 通过封装方法可以有效减少耦合
      • 耦合:模块与模块之间,代码与代码之间的关联程度,对属性封装后,和调用相关的代码就会变得相对简单,可以降低耦合

    2. 如何进行封装

    在进行封装时都是出于对属性保护的考虑,可以按照以下两个步骤来进行:

    • 使用权限修饰符
      • 使用private作用在属性上,关闭直接访问的入口
      • 使用public作用在方法上,提供调用的入口
    • 定义与属性存取相关的方法

    在属性关闭后,我们需要通过方法来获取属性的值以及对属性值进行修改。由于有了方法结构,我们就可以对存入的数据进行判断,对不符合逻辑的数据进行处理。

    3. 常规封装方法

    明白了封装的作用后,我们可以通过自定义方法的方式完成对属性的封装。封装方法和类中定义的其他方法在结构上没有任何的区别,同样都是普通的方法,区别主要在于体现在用途方面:

    • 普通方法主要表达该类所能产生的行为
    • 封装方法主要为属性的访问和使用提供了一个入口,作用相对单一

    在进入到框架的学习之后,很多对实体类属性自动赋值的操作都是通过调用封装方法实现的,所以我们必须要知道常规封装方法的名称定义和类型设置规则。
    对于属性来说我们只会进行两种操作:存和取。那么相应的封装方法应该有一对儿

    • get代表取用:既然是取值,那么就要把属性值进行返回,方法的返回值类型与属性类型相同
    • set代表存储:既然是存值,那么就要在参数列表中接收想要存入的值,类型与属性类型相同

    对于命名方面只要遵从驼峰命名法就好,以get或set开头,大写属性名称的首字母,其余不变,看下面一个例子:

    public class Person{
        // 使用private声明属性
        private String name;
        private double money;
    
        // 使用public声明方法,作为操作属性的入口
        public void setName(String name){
            this.name = name;
        }
        public String getName(){
            return this.name;
        }
        public void setMoney(double money){
            // 如有需要,可以在方法中可以自定义其他逻辑
            this.money = money;
        }
        public double getMoney(){
            return this.money;
        }
    }
    

    由于常规封装方法定义的格式和名称都相对固定,所以一般的编译器都自带自动生成封装方法的功能,这样既方便又能降低出错率,大家一定要掌握。

    • Eclipse:

    属性定义完成后,选择source菜单 -> Generate Getters and Setters…
    在这里插入图片描述
    点击Select All(选择所有属性) -> Generate
    在这里插入图片描述

    • IDEA:

    与Eclipse类似,在定义好类的私有属性后,使用快捷键:Alt + Insert

    可以一次性选择多个属性 -> 点击OK

    扫描下方二维码,加入官方粉丝微信群,可以与我直接交流,还有更多福利哦~

    在这里插入图片描述

    展开全文
  • Java面向对象编程特征 - 继承

    千次阅读 多人点赞 2020-03-31 18:24:08
    本文关键字:Java、面向对象特征、继承。继承是面向对象编程的特征之一,继承将面向对象的编程思想体现的更加淋漓尽致,允许类和类之间产生关联。

    写在前面:博主是一只经过实战开发历练后投身培训事业的“小山猪”,昵称取自动画片《狮子王》中的“彭彭”,总是以乐观、积极的心态对待周边的事物。本人的技术路线从Java全栈工程师一路奔向大数据开发、数据挖掘领域,如今终有小成,愿将昔日所获与大家交流一二,希望对学习路上的你有所助益。同时,博主也想通过此次尝试打造一个完善的技术图书馆,任何与文章技术点有关的异常、错误、注意事项均会在末尾列出,欢迎大家通过各种方式提供素材。

    • 对于文章中出现的任何错误请大家批评指出,一定及时修改。
    • 有任何想要讨论和学习的问题可联系我:zhuyc@vip.163.com。
    • 发布文章的风格因专栏而异,均自成体系,不足之处请大家指正。

    Java面向对象编程三大特征 - 继承

    本文关键字:Java、面向对象、三大特征、继承


    继承是面向对象编程的三大特征之一,继承将面向对象的编程思想体现的更加淋漓尽致,允许类和类之间产生关联,对于类和对象的基本知识可进传送门:Java中的基本操作单元 - 类和对象

    一、思想解读

    1. 什么是继承

    从类的概念出发,我们可以通过定义class去描述一类事物,具有相同的属性和行为。但在很多时候我们希望对类的定义能够进一步细化,这就相当于是一个大的分类下面有很多的子分类,如文具下面可以分为:写字笔、便签、文件管理等等。

    如果品类更加的复杂,可以先分为:学生文具、办公文具、财会用品,然后在每个品类下面再根据具体的作用去划分。这些被划分出来的子类别都一定具有父类别的某些共同特征或用途,并且有可能存在多级的分类关系,那么如果我们使用面向对象的语言去描述出这样一种关系就可以使用继承。

    下面我们将例子与面向对象中的概念进行对应:

    • 上述关系可以用子类别继承自父类别来描述
    • 父类别被称作父类或超类
    • 子类别被称作子类
    • 继承可以使子类具有父类的各种属性和方法,不需要再次编写相同的代码

    2. 继承有什么用

    如果我们将学生类进一步细化为:初中生、高中生、大学生。显然,细化之后的类与类之间一定是存在某些差异的,但是也一定会存在共同点。如果我们使用代码进行表示,三个类中会有很多相同的属性或方法,也会存在一些差异:

    // 定义类:初中生
    public class JuniorStudent{
        // 相同的属性
        public String name;
        public int age;
        public String school;
        public String grade;
        // 其他方法
    }
    
    // 定义类:高中生
    public class SeniorStudent{
        // 相同的属性
        public String name;
        public int age;
        public String school;    
        public String grade;
        // 不同的属性
        public String subject;// 科目:文理科
        // 其他方法
    }
    
    // 定义类:大学生
    public class UniversityStudent{
        // 相同的属性
        public String name;
        public int age;
        public String school;
        public String grade;
        // 不同的属性
        public String college;// 学院
        public String major;// 专业
        // 其他方法
    }
    

    上面只是列举了部分的属性,可以发现有很多属性是完全重合的,方法也有可能存在相同的现象。这个时候我们就们就可以将其中相同的属性和方法抽取出来,定义一个Student学生类,从而对每个类进行简化。

    // 定义类:学生
    public class Student{
        // 提取公共的属性
        public String name;
        public int age;
        public String school;
        public String grade;
        // 提取公共的方法
    }
    
    // 简化后的初中生
    public class JuniorStudent extends Student{
        // 其他方法
    }
    
    // 简化后的高中生
    public class SeniorStudent extends Student{
        // 不同的属性
        public String subject;// 科目:文理科
        // 其他方法
    }
    
    // 简化后的大学生
    public class UniversityStudent extends Student{
        // 不同的属性
        public String college;// 学院
        public String major;// 专业
        // 其他方法
    }
    
    // 定义测试类
    public class Test{
        public static void main(String[] args){
            JuniorStudent juniorStudent = new JuniorStudent();
            juniorStudent.name = "小明";// 正常使用,来自父类
            SeniorStudent seniorStudent = new SeniorStudent();
            seniorStudent.name = "小李";// 正常使用,来自父类
            seniorStudent.subject = "文科";// 自有属性,来自子类
            UniversityStudent universityStudent = new UniversityStudent();
            universityStudent.name = "小陈";// 正常使用,来自父类
            universityStudent.college = "XX大学";// 自有属性,来自子类
            universityStudent.major = "XX专业";// 自有属性,来自子类
        }
    }
    

    从上面的例子可以看出,子父类之间可以通过extends关键字建立继承关系。子类可以直接使用父类中定义的属性和方法,也可以覆盖父类中的方法,表现出子类自己的特点。使用继承有以下几个好处:

    • 减少代码量,子类可以继承父类的属性和方法
    • 提高复用性,便于维护
    • 子类可以通过覆盖父类的方法表达自身的特点
    • 可以使类和类之间产生关联,是多态的前提

    3. 继承的限制与规则

    在Java中,继承的使用存在一些限制,我们需要先明确使用规则才能更好的去设计子父类。一言以蔽之:Java不支持多继承,但支持多重继承(多级继承),从一个子类出发,只存在一条路找到最终的父类

    • 单继承
    class A{
        ...
    }
    class B extends A{
        ...
    }
    
    • 多重继承
    class A{
        ...
    }
    class B extends A{
        ...
    }
    class C extends B{
        ...
    }
    
    • 多子类继承同一父类
    class A{
        ...
    }
    class B extends A{
        ...
    }
    class C extends A{
        ...
    }
    

    4. 如何设计子父类

    当我们需要通过程序去描述某一个场景或实现某一个应用系统时,就需要构建很多相关的类,合理的使用继承可以使代码更加高效也更加利于维护。那么子父类的构建就可以从类本身所代表的意义出发,如果含义相似或相近,并且类与类之间没有较大的冲突,那么我们就可以把他们归为一类。另外一种情况就是原有构建的类不能满足新功能的需要,需要据此改进,那么我们就可以将原有类作为父类,扩充出他的子类,使整体的功能更加强大,同时又不会对已有的代码产生较大的影响。

    • 从多个相关联的类中提取出父类

    可以从管理员(AdminUser)、普通用户(NormalUser)、VIP用户(VIPUser)中提取相同的特征,得到父类:用户(User),同样具有用户名,密码,昵称等信息,同样存在登录方法,只不过各自的实现会有所不同。我们也可以混合使用多种继承方式,得到如下的类关系:

    • 从一个已有的类中扩充出子类

    对于一个简单的电商场景,产品类的设计会比较简单,只需要标识基本信息和价格即可。如果此时需要举行一个秒杀活动,要在购买页面中标识出原价、特价、活动时间、活动介绍等等信息,这就使得我们要对产品类做出升级,如果直接去修改产品类,会导致出现一些可能不会经常使用的属性和方法,因为这些属性和方法纯粹是为特价商品而设计的。比较好的做法是将原有的商品类(Product)作为父类,然后扩充出它的子类:特价商品类(SpecialProduct),在特价商品类中存放新出现的信息。

    • 子类是父类的一个扩充和扩展,使用extends关键字来表示真的是很恰当

    二、子父类的使用

    理解了相关的概念后,我们回到Java的语法中来,子父类间通过extends来建立继承关系,结构如下:

    // 定义父类
    public class Father{
        ...
    }
    
    // 定义子类,继承父类
    public class Son extends Father{
        ...
    }
    

    1. 权限修饰符

    在之前的文章中,已经介绍了权限修饰符的用法,不清楚的同学可以进传送门:Java面向对象编程三大特征 - 封装。当两个类建立了继承关系时,虽然父类当中的所有内容均会被子类继承,但是由于存在权限修饰符,无访问权限的属性或方法会被隐藏,无法被调用和访问(实例化子类对象时,父类对象也会一同被实例化,详细过程会在后面的文章中单独说明)。
    在子类中可以直接调用父类中被public和protected声明的属性和方法,如果是在测试类中,在进行属性调用时依然会受到权限修饰符的限制,看下面一个例子:

    src
    └──edu
        └──sandtower
            └──bean
                │    Father.java
                │    Son.java
            └──test
                │    Test.java
    

    以上为实体类与测试类所在的目录结构

    • Father实体类所在包:edu.sandtower.bean
    • Son实体类为Father的子类,与Father在同一包下
    • Test测试类所在包:edu.sandtower.test
    package edu.sandtower.bean;
    
    public class Father{
        // 父类中的私有属性
        private double ownMoney = 2000;// 私房钱
        // 父类中的受保护属性
        protected double money = 5000;
        // 父类中的公开属性
        public String name = "老李";
    }
    
    package edu.sandtower.bean;
    
    public class Son extends Father{
        // 子类中的独有属性
        ...
        // 测试方法
        public void test(){
            Son son = new Son();
            System.out.println(son.ownMoney);// 编译失败,无法访问私有属性,查看私房钱
            System.out.println(son.money);// 编译通过,在子类中可以访问protected属性
            System.out.println(son.name);// 编译通过,可以访问public属性
        }
    }
    
    package edu.sandtower.test;
    
    import edu.sandtower.bean.Son;
    
    public class Test{
        public static void main(String[] args){
            // 在test包中的Test类中创建Son实例
            Son son = new Son();
            son.name = "小李";// 编译通过,可以访问自父类继承的公开属性
            // 编译失败,在测试类中无法访问protected属性,因为Test类与Father类并无子父类关系
            son.money -= 500.0;
            // 对于Son的其他属性和Father的使用可以自行进行测试,不再赘述
        }
    }
    

    从上面的例子可以看到,权限修饰符所起的作用还是很大的。测试类对于子父类来说是一个处在不同包中的完全无关的类,在调用时会被权限修饰符所限制,所以这里也再度明确一下:权限修饰符是根据类的所在路径与类之间的结构关系进行限定的,不是说在任意一个地方使用子类实例都能调用出父类中的属性和方法。

    2. this与super

    明确了权限修饰符的作用规则后就带来了一个问题,既然在其他类中不能够访问某些属性,那应该如何赋值和使用呢?这时就可以使用封装的办法,同时结合this和super的使用来解决。

    • this:指代当前对象,可以调用当前类中的属性和方法
    • super:指代父类对象,可以调用父类中可访问的属性和方法,包括被子类覆盖重写的方法

    在使用子类实例时,如果我们想要使用某些父类的属性或方法,可以借助构造器和封装方法。将代码修改后,得到如下结果:

    package edu.sandtower.bean;
    
    public class Father{
        // 父类中的私有属性
        private double ownMoney = 2000;// 私房钱
        // 父类中的受保护属性
        protected double money = 5000;
        // 父类中的公开属性
        public String name = "老李";
    }
    
    package edu.sandtower.bean;
    
    public class Son extends Father{
        // 子类中的独有属性
        ...
        // 使用构造器为属性赋值
        public Son(String name,double money){
            super.name = name;
            super.money = money;
        }
        // 使用封装方法操作父类中的属性
        public void setMoney(double money){
            super.money = money;
        }
        public double getMoney(){
            return super.money;
        }
    }
    
    package edu.sandtower.test;
    
    import edu.sandtower.bean.Son;
    
    public class Test{
        public static void main(String[] args){
            // 在test包中的Test类中创建Son实例
            Son son = new Son("小李",3000);// 成功为父类继承而来的属性赋值
            // 以下代码编译通过
            double money = son.getMoney();
            System.out.println(money);
            son.setMoney(money - 500);
        }
    }
    

    3. final修饰符

    final修饰符可以用来修饰属性和方法,也可以用来修饰类。
    当修饰属性时,如果是基本数据类型,则可看做是定义了一个常量,值一旦被指定则不可变。如果是引用类型,则引用无法发生变化,即:可以修改数组或实例中的属性值,但是引用的指向不能再发生变化,无法再指向其他的实例和数组。

    由final修饰的方法被子类继承后不能被重写,有关于继承中子父类方法的关系将在论述多态的文章中详细讨论
    由final修饰的class不能被继承,如果我们把继承关系想象成一棵大树,父类为根,子类为枝的话,那么final class就一定只能做树叶了,因为确认不会有它的子类存在了。

    4. 终极父类:Object

    在刚接触面向对象时,我们可能就听说过一个类,那就是:Object,好像它无所不能装,大饼夹一切的存在。我们所有定义的class都会隐式的继承Object,即:如果我们的类没有使用extends关键字显示的指定父类,那么会自动认为Object是父类,这一过程是在JVM运行时完成的,所以我们不能通过反编译来进行验证。
    Object中提供了特别通用的方法,如:toString,hashCode,equals等等。那么为什么使用Object能装下一切呢?首先就是因为Object类一定是最终父类的存在,换句话说就是树根本根!因为如果一个类显示的指定了另外一个类作为父类,那么他的父类或者父类的父类,一定会在某一级隐式的继承Object。
    如果想进一步了解为什么任意类型的对象实例都能使用Object类型的引用接收可以查看另外一篇文章:Java面向对象编程三大特征 - 多态

    扫描下方二维码,加入官方粉丝微信群,可以与我直接交流,还有更多福利哦~

    在这里插入图片描述

    展开全文
  • 面向对象最重要的三个基本特征

    千次阅读 2016-03-08 23:01:41
    面向对象三个基本特征是:封装、继承、多态。
  • Java面向对象三特征

    千次阅读 2020-09-26 21:21:24
    Java面向对象三特征 1.重写 ​ **概念:**子类继承父类的以后,可以对父类中同名参数的方法进行覆盖的操作。 ​ 应用: 重写以后,创建子类对象后,子类调用父类中同名同参数的方法时,实际上调用的是子类重写后的...
  • Python 面向对象三特征

    千次阅读 2018-05-18 20:51:51
    一、 面向对象三特征--封装面向对象的程序设计中,某个类把所需要的数据(也可以说是类的属性)和对数据的操作(也可以说是类的行为)全部都封装在类中,分别称为类的成员变量和方法(或成员函数)。这种把成员...
  • Java面向对象编程特征 - 多态

    千次阅读 多人点赞 2020-04-06 11:43:48
    本文关键字:Java、面向对象特征、多态。多态是面向对象编程的特征之一,是面向对象思想的终极体现之一。在理解多态之前需要先掌握继承、重写、父类引用指向子类对象的相关概念。
  • 面向对象三特征介绍

    千次阅读 2019-06-18 16:05:20
    面向过程和面向对象区别 我们都常听到软件设计思想有面向对象和面向过程。那么什么是面向对象、什么是面向过程呢? 接下来我举例子说明一下他们两者的区别。 有一天你想吃鱼香肉丝,怎么办,有两选择。 第一...
  • python中面向对象三特征

    千次阅读 2018-09-13 20:21:05
    面向对象三特征  1.封装:根据职责将属性和方法封装到一抽象的类中  2.继承:实现代码的重用,相同的代码不需要重复的写  3.多态:以封装和继承为前提,不同的子类对象调用相同的方法,产生不同的执行结果 一...
  • 面向对象编程的三个基本特征

    万次阅读 2016-04-22 13:50:51
    三个基本特征面向对象三个基本特征是:封装、继承、多态。封装封装最好理解了。封装是面向对象特征之一,是对象和类概念的主要特性。 封装,也就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让...
  • c#总结--面向对象三特征

    千次阅读 热门讨论 2017-03-05 22:01:05
    前言 想要学好面向对象编程,除了掌握语法结构外,还需要熟悉面向对象特征:封装、继承、多态,这特征不是相互独立的,而是相互关联的,你中有我、我中有你。封装定义:隐藏对象的属性和方法,设置不同的...
  • Java中面向对象三特征总结

    万次阅读 多人点赞 2017-07-09 14:13:36
    JAVA中面向对象特征:  面向对象具有继承性(Inheritance)  面向对象具有多态性(Polymorphism)  面向对象具有封装性(Encapsulation) 一、继承  多类具有共同的属性(成员变量)与行为(成员...
  • 详细说明面向对象特征面向对象 把数据及对数据的操作方法放在一起,作为一相互依存的整体–对象。对同类对象抽象其共性,形成类。类中的大多数数据,只能在本类的方法进行处理。类通过一简单的外部...
  • 面向对象三个基本特征(讲解)

    千次阅读 2018-12-04 09:26:00
    面向对象三个基本特征(讲解)面向对象三个基本特征是:封装、继承、多态。 封装封装最好理解了。封装是面向对象特征之一,是对象和类概念的主要特性。 封装,也就是把客观事物封装成抽象的类,并且类...
  • 面向对象是为了解决系统的可维护性,可扩展性,可重用性。但是面向对象为什么可以解决这些问题呢? 面向对象产生的历史原因有下面两点: 1、计算机是帮助人们解决问题的,然而计算机终究是机器,他只会按照人所写...
  • 面向对象三特征之一封装性

    千次阅读 2017-01-18 16:34:44
    一、面向对象特征 封装 (Encapsulation) 继承 (Inheritance) 多态 (Polymorphism)二、封装1、什么是封装 封装:是指隐藏对象的属性和实现细节,仅对外提供公共访问方式。2、封装的分类与好处 狭义的封装...
  • Python 面向对象三特征之多态

    千次阅读 2020-02-14 09:23:15
    【摘要】 面向对象大特性多态相关知识。 多态 1、多态 多态指的是一类事物有多种形态 动物有多种形态:人,狗,猪 import abc class Animal(metaclass=abc.ABCMeta): #同一类事物:动物 @abc.abstract...
  • 面向对象三特征和解决的问题

    千次阅读 2014-02-04 14:32:07
    一:什么是“对象” 在计算机的世界里,对象(Object)就是...二:什么事面向对象 面向对象主要是指程序的设计方法。他主要有特征:封装、继承、多态 :什么是封装? 在软件设计中,封装是指将接口与实现显式
  • 程序的三个基本结构,面向对象三个特征 程序的三个基本结构,顺序,选择,循环。 面向对象程序设计三个特征:封装,继承,多态。
  • java面向对象三特征及五大原则

    千次阅读 2019-12-28 17:36:56
    一、java面向对象特征 1、封装(Encapsulation) 封转是指属性私有化 根据需要提供setter和getter方法来访问属性 隐藏具体属性和实现细节,仅对外开放接口 控制程序中属性的访问级别 目的:增强数据安全性,不...
  • java面向对象三特征 — 封装

    万次阅读 2017-04-26 21:59:41
    权限修饰符:控制变量等其他东西的可见范围。public :公共的。public修饰的成员变量或方法任何人都可以访问。private :私有的。... 提供一公共的方法设置或者获取该私有的成员属性。 命名规范: set 属性名();
  • 关于面向对象以及特征的解释

    千次阅读 2018-05-14 22:32:30
    关于面向对象以及特征的解释面向对象: 在C语言编程中是面向过程而在Java编程中是面向对象的。面向过程更重要的是看重实现的具体过程,面向对象看重的是结果,不管其里面的具体过程,只看结果。 举一例子:...
  • 摘要:多态从字面意思上看就是多种形态,在我们python的面向对象里就是不同的对象在接收相同方法或者函数时会产生不同的行为,也就是说,每对象可以用自己的方式去响应共同的函数,不同的方式实现不同的结果。...
  • 面向对象三个特征及其优缺点

    千次阅读 2017-07-24 20:48:42
    类可以将自身的数据和方法给可信的类或者对象操作,对不可信的进行隐藏信息。 2、继承  可以在现有类的基础上无需重写,扩展类的功能.  通过继承创建的新类称之为"子类"、"派生类". 被继承的类称之为"基类...
  • 面向对象编程的特征

    千次阅读 2019-04-10 20:42:12
    面向对象编程的特征:封装、继承、多态 一:封装 对于封装而言,一对象它所封装的是自己的属性和方法,所以他是不需要依赖其他对象就可以完成自己的操作。 封装的大好处: 1、良好的封装能够减少耦合。 2、...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 669,098
精华内容 267,639
关键字:

面向对象三个特征