多态

Java基础 学习笔记4

ぐ巨炮叔叔 提交于 2020-02-27 18:42:45
1.继承 继承是类与类的一种关系;Java中的继承是单继承,只有一个父类。 继承的好处:子类直接拥有父亲的所有属性和方法(private修饰的无效!),可实现代码复用。 语法规则: class 子类 extends 父类 eg:class Dog extends Animal{ … } 2.Java中的方法重写 如果子类对继承父类的方法不满意,是可以重写父类继承的方法的,当调用方法时会优先调用子类的方法。 语法规则:返回值类型,方法名,参数类型及个数都要与父类继承的方法相同,才叫方法的重写。 3.Java中的继承初始化顺序 a.初始化父类再初始化子类。(使用构造方法可以看出,虽然仅创建了子类的对象,但是先执行了父类的构造方法,之后才执行子类的构造方法)。 b.先执行初始化对象中的属性,再执行构造方法中的初始化。 4.Java中final的使用 final关键字: 表示“最终的”,即不可修改。 final可以修饰类、方法、属性和变量 a.修饰类:该类不允许被继承 b.修饰方法:该方法不允许被重写 c.修饰属性:则该属性不会进行隐式初始化(不会自动初始化,之前我们没有初始化都是系统帮我们自动初始化),需要手动初始化或者在构造方法中初始化 (但二者只能选一,即只能初始化一次后便不能更改) d.修饰变量,只能在声明的时候赋一次值,成为常量(static final 会使其成为全局常量)。

Java 基础 接口和多态

帅比萌擦擦* 提交于 2020-02-27 08:58:26
接口 接口的概念   接口是功能的集合,同样可看做是一种数据类型,是比抽象类更为抽象的”类”。   接口只描述所应该具备的方法,并没有具体实现,具体的实现由接口的实现类(相当于接口的子类)来完成。这样将功能的定义与实现分离,优化了程序设计。   请记住:一切事物均有功能,即一切事物均有接口。 接口的定义   与定义类的class不同,接口定义时需要使用interface关键字。   定义接口所在的仍为.java文件,虽然声明时使用的为interface关键字的编译后仍然会产生.class文件。这点可以让我们将接口看做是一种只包含了功能声明的特殊类。    定义格式: public interface 接口名 { 抽象方法1; 抽象方法2; 抽象方法3; }   使用interface代替了原来的class,其他步骤与定义类相同:    接口中的方法均为公共访问的抽象方法    接口中无法定义普通的成员变量   类实现接口   类与接口的关系为实现关系,即类实现接口。实现的动作类似继承,只是关键字不同,实现使用implements。    其他类(实现类)实现接口后,就相当于声明:”我应该具备这个接口中的功能”。实现类仍然需要重写方法以实现具体的功能: class 类 implements 接口 { 重写接口中方法 }   在类实现接口后,该类就会将接口中的抽象方法继承过来

浅谈面向对象特征

血红的双手。 提交于 2020-02-27 05:53:32
所有的面相对象思想,归根结底是为了简化代码,减少代码量,构建更符合现实生活逻辑的程序代码,从而减轻程序员的负担。不能一味地或者说刻意地去使用面相对象的思想而忽略了程序所实现的功能或者框架,要根据实际情况 众所周知,面向对象编程的特点为:封装、继承、多态。C#是一门完全面向对象的语言,由于比Java推出的时间还要晚,所以对面向对象的思想的体现比Java还要完美,那么在C#中如何体现封装、继承和多态呢?下面举例并进行说明。 1.封装 封装的好处有以下几点: ①数据不外泄,可以做到一定的保护 ②类的使用者不用考虑具体的数据运算,方便 ③程序结构性强,层次清晰,便于维护 对相关的字段、方法进行封装固然对面向对象编程起到不可缺少的重要作用,但并不代表不可以访问类或者说具体的实例化对象中的内容,而且为使用者提供接口,仅仅让他们调用就可以了,他们只做他们的工作,不需要考虑或者顾及你写的类具体是做什么的,更不用考虑你写的每一行代码是什么意思。 在C#中,对于变量的封装,往往将需要被在本类以外调用的,以属性的形式出现,而不像C++中是直接以public成员或者private成员加上相关的方法调用,那样要么不符合面向对象的特点,要么太麻烦。 C#中属性的声明: 代码如下: public class TestClass { public string Info { get; set; } }

构造函数不可虚,析构可以虚

痴心易碎 提交于 2020-02-27 04:41:01
一.什么是虚函数: 可以让成员函数操作一般化,用基类的指针指向不同的派生类的对象时, 基类指针调用其虚成员函数,则会调用其真正指向对象的成员函数, 而不是基类中定义的成员函数(只要派生类改写了该成员函数)。 若不是虚函数,则不管基类指针指向的哪个派生类对象,调用时都 会调用基类中定义的那个函数。 例 class A { virtual void AAA() { cout<<"这是基类的!"; } }; class a:A { void AAA() { cout<<"这是派生类a!"; } }; 然后你生成a的实例,调用AAA()方法时,程序调用的是a中的AAA,而不是A中的AAA 如果你不定义virtual,在生成a的实例后调用的是基类的AAA() 二.构造函数不可定义为虚函数: 1,从存储空间角度 虚函数对应一个vtable,这大家都知道,可是这个vtable其实是存储在对象的内存空间的。问题出来了,如果构造函数是虚的,就需要通过 vtable来调用,可是对象还没有实例化,也就是内存空间还没有,无法找到vtable,所以构造函数不能是虚函数。 2,从使用角度 虚函数主要用于在信息不全的情况下,能使重载的函数得到对应的调用。构造函数本身就是要初始化实例,那使用虚函数也没有实际意义呀。所以构造函数没有必要是虚函数。

构造函数不可虚,析构可以虚

久未见 提交于 2020-02-27 04:34:05
一.什么是虚函数: 可以让成员函数操作一般化,用基类的指针指向不同的派生类的对象时, 基类指针调用其虚成员函数,则会调用其真正指向对象的成员函数, 而不是基类中定义的成员函数(只要派生类改写了该成员函数)。 若不是虚函数,则不管基类指针指向的哪个派生类对象,调用时都 会调用基类中定义的那个函数。 例 class A { virtual void AAA() { cout<<"这是基类的!"; } }; class a:A { void AAA() { cout<<"这是派生类a!"; } }; 然后你生成a的实例,调用AAA()方法时,程序调用的是a中的AAA,而不是A中的AAA 如果你不定义virtual,在生成a的实例后调用的是基类的AAA() 二.构造函数不可定义为虚函数: 1,从存储空间角度 虚函数对应一个vtable,这大家都知道,可是这个vtable其实是存储在对象的内存空间的。问题出来了,如果构造函数是虚的,就需要通过 vtable来调用,可是对象还没有实例化,也就是内存空间还没有,无法找到vtable,所以构造函数不能是虚函数。 2,从使用角度 虚函数主要用于在信息不全的情况下,能使重载的函数得到对应的调用。构造函数本身就是要初始化实例,那使用虚函数也没有实际意义呀。所以构造函数没有必要是虚函数。

构造函数为什么不能为虚函数 & 基类的析构函数为什么要为虚函数

亡梦爱人 提交于 2020-02-27 03:24:15
一、构造函数为什么不能为虚函数 1. 从存储空间角度,虚函数相应一个指向vtable虚函数表的指针,这大家都知道,但是这个指向vtable的指针事实上是存储在对象的内存空间的。问题出来了,假设构造函数是虚的,就须要通过 vtable来调用,但是对象还没有实例化,也就是内存空间还没有,怎么找vtable呢?所以构造函数不能是虚函数。 2. 从使用角度,虚函数主要用于在信息不全的情况下,能使重载的函数得到相应的调用。构造函数本身就是要初始化实例,那使用虚函数也没有实际意义呀。所以构造函数没有必要是虚函数。虚函数的作用在于通过父类的指针或者引用来调用它的时候可以变成调用子类的那个成员函数。而构造函数是在创建对象时自己主动调用的,不可能通过父类的指针或者引用去调用,因此也就规定构造函数不能是虚函数。 3. 构造函数不须要是虚函数,也不同意是虚函数,由于创建一个对象时我们总是要明白指定对象的类型,虽然我们可能通过实验室的基类的指针或引用去訪问它但析构却不一定,我们往往通过基类的指针来销毁对象。这时候假设析构函数不是虚函数,就不能正确识别对象类型从而不能正确调用析构函数。 4. 从实现上看,vbtl在构造函数调用后才建立,因而构造函数不可能成为虚函数从实际含义上看,在调用构造函数时还不能确定对象的真实类型(由于子类会调父类的构造函数);并且构造函数的作用是提供初始化,在对象生命期仅仅运行一次

C++笔记(3):一些C++的基础知识点

99封情书 提交于 2020-02-26 23:05:08
前言: 找工作需要,最近看了下一些C++的基本概念,为范磊的 《零起点学通C++》,以下是一些笔记。 内容:   delete p;只是删除指针p指向内存区,并不是删除指针p,所以p还是可以用的。删除空指针所指向内存是可以的。   堆中的变量和对象时匿名的,没有名称,只能通过指针来访问。   在堆中创建对象时,在分配内存的同时会调用类的构造函数,在删除堆中对象时,会调用类的析构函数。   为了避免内存泄露,在删除一个指针后应该将其其值赋为0。   常量指针是指针指向的内存区域地址不能改变,但是该内存地址里保存的值是可以改变的,比如int a; int * const p = &a;   指向常量的指针表示指针指向的对象是不能被修改的,但是该指针可以被修改,即该指针可以指向另一块目标内存地址。比如const int a = 0; const int *p = &a; 如果A是一个类,也可以为const A* p = new A;   而指向常量的常指针表示指针本身不能被修改,其指向的内存地址内容也不能被修改。比如const int a = 0; const int * const p = &a;   引用就是别名常量。   堆中的地址是用指针来操作的,用不到别名。   如果在main函数前面的其它函数的声明和定义是一起的,则表明这个函数是内联函数!因此当该函数较长时

转行小白成长路-java篇

淺唱寂寞╮ 提交于 2020-02-26 22:25:21
第8章:多态   多态,同种类型的不同的存在状态。在此之前我一直有个困惑,多个类实现同一个接口,如何按不同场景应用不同的实现类。现在想来要想实现这种想法是不现实的,正确的思路应该是一个接口被多个接口继承(为了不同场景),然后在分别实现,调用接口的时候,就调用二层的接口,实现了唯一实现类与一个接口绑定。多态主要用在继承,为了扩展导出类,主要方向在于扩展类型,覆盖掉基类的方法,修改成专门针对导出类型的方法。   对于参数的多态性,具体的实现思路应该是运行时将某一类的对象传进去,这就是后期绑定,然后根据是否继承自基类(或者object)判断同种类型。值得注意的是static和final是前期绑定,就是编译时期就知道相应的地址,这是因为这两种修饰的对象的生命周期是同类一样长,他们具有唯一性,与动态绑定就没有什么关系了。涉及到这种引用的调整,肯定都是非常谨慎的,所以不管是上转型还是下转型都要进行检查(RTTI)。具体执行的顺序就要jvm阶段具体分析。   继承与接口类似,都是最好使用is-a的形式设计,这样可以最大的限度减低问题的发生,如果使用is-like-a就要涉及到上转型,新添加的方法没什么用,只能修改方法里面的内容,只能先上转型才能下转型。 来源: https://www.cnblogs.com/aiwin/p/12369414.html

Java继承和多态

血红的双手。 提交于 2020-02-26 12:06:02
一、继承 1.定义: 当我们定义很多部分具有相同的属性和行为的类时,为了允许使用现有类的功能,并在无需改写原来的类的情况下,引入 继承 的概念。 我们把允许重用现有类称为基类(父类),由基类派生出来的类称为派生类(子类)。 2.基本语法: ```java class 类名 extends 父类名{ } java类的继承通过关键字extends完成,子类继承父类所有的属性和行为。 如果没有指定的父类,那么java编译器默认该类的父类为Object。 代码示例: class Animal { protected String name ; protected int age ; protected String sex ; public Animal ( String name ) { this . name = name ; } public void eat ( ) { System . out . println ( name + " eat" ) ; } } class Cat extends Animal { public Cat ( String name ) { //编译器默认调用的是父类的默认构造函数,super()可以省略 super ( name ) ; //如果父类只有一个带参数的构造函数,这里不能省略 this . name = name ; } public

面向对象的三大特征

蓝咒 提交于 2020-02-26 07:29:10
面向对象的三大特征:封装、继承、多态 封装 封装,就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。一个类就是一个封装了数据以及操作这些数据的代码的逻辑实体。在一个对象内部,某些代码或某些数据可以是私有的,不能被外界访问。通过这种方式,对象对内部数据提供了不同级别的保护,以防止程序中无关的部分意外的改变或错误的使用了对象的私有部分。 继承 继承,指可以让某个类型的对象获得另一个类型的对象的属性的方法。它支持按级分类的概念。继承是指这样一种能力:它可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。 通过继承创建的新类称为“子类”或“派生类”,被继承的类称为“基类”、“父类”或“超类”。继承的过程,就是从一般到特殊的过程。要实现继承,可以通过 “继承”(Inheritance)和“组合”(Composition)来实现。继承概念的实现方式有二类:实现继承与接口继承。实现继承是指直接使用 基类的属性和方法而无需额外编码的能力;接口继承是指仅使用属性和方法的名称、但是子类必须提供实现的能力。 多态 多态,是指一个类实例的相同方法在不同情形有不同表现形式。多态机制使具有不同内部结构的对象可以共享相同的外部接口。这意味着,虽然针对不同对象的具体操作不同,但通过一个公共的类,它们(那些操作