黑马程序员_Java基础面向对象之继承

继承的作用:
1、提高了代码的复用性
2、让类与类之间产生了关系,有了这个关系,才有了多态的特性。

注意:
千万不要为了获取其他类的功能,简化代码而继承。
必须是类与类之间有所属关系才可以继承。所属关系:is a。

Java语言中,Java只支持单继承,不支持多继承。
因为多继承容易带来安全隐患:当多个父类中定义了相同功能时,但功能内容不同时,子类不确定要运行哪一个。
但是java保留了这种机制,并用另一种体现形式来完成表示。多实现。
Java支持多层继承,也就是一个继承体系。

如何使用一个继承体系中的功能呢?
想要使用体系,先查阅体系父类的描述,因为父类中定义的是该系中共性功能
通过了解共性功能,就可以知道该体系的基本功能。
那么这个体系已经基本可以使用了。
那么在具体调用时,要创建最子类的对象。
原因:一是有可能父类不能创建对象;二是创建子类对象可以使用更多的功能。包括基本的也包括特有的。
简单一句话,查阅父类功能,创建子类对象使用功能。

class A                                                 
     {
         void show()
         {
             System.out.println("a");
         }
     }
class B
     {
         void show()
         {
             System.out.println("b");
         }
     }
class C extends A,B
     {}
     C c = new C ();                                       
     c.show();
```此段代码无法确定打印结果
![这里写图片描述](http://img.blog.csdn.net/20150825100943339)
继承的概念:
类的继承是面向对象程序设计的一个重要特点,通过继承可以实现代码的复用,被继承的类称为父类或超类(superclass),由继承而得到的类称为子类(subclass)。一个父类可以同时拥有多个子类,但由于Java中不支持多重继承,所以一个类只能有一个直接父类。在Java语言中有一个称为java.lang.Object的特殊类,所有的类都是直接或间接地继承该类而得到的。
使用extends关键字来实现继承。
被继承的类称为父类(超类),继承别的类的类称为子类。1.子类继承父类的成员变量
  当子类继承了某个类之后,便可以使用父类中的成员变量,但是并不是完全继承父类的所有成员变量。具体的原则如下:
  1)能够继承父类的publicprotected成员变量;不能够继承父类的private成员变量;
  2)对于父类的包访问权限成员变量,如果子类和父类在同一个包下,则子类能够继承;否则,子类不能够继承;
  3)对于子类可以继承的父类成员变量,如果在子类中出现了同名称的成员变量,则会发生隐藏现象,即子类的成员变量会屏蔽掉父类的同名成员变量。如果要在子类中访问父类中同名成员变量,需要使用super关键字来进行引用。
  2.子类继承父类的方法
  同样地,子类也并不是完全继承父类的所有方法。
  1)能够继承父类的publicprotected成员方法;不能够继承父类的private成员方法;
  2)对于父类的包访问权限成员方法,如果子类和父类在同一个包下,则子类能够继承;否则,子类不能够继承;
3)对于子类可以继承的父类成员方法,如果在子类中出现了同名称的成员方法,则称为覆盖,即子类的成员方法会覆盖掉父类的同名成员方法。如果要在子类中访问父类中同名成员方法,需要使用super关键字来进行引用。





<div class="se-preview-section-delimiter"></div>

这里写代码片
“`

class dog                                              
  {
      public void eat()
      {
          System.out.println("eat");
      }
      public void speak()
      {
          System.out.println("spaeak");
      }
  }
```这两个类猫和狗都有吃和说话两个属性,但是二者之间却不能够产生继承的关系。要是想产生继承关系的话,那就再定义一个新的类animal,猫和狗共同的父类。





<div class="se-preview-section-delimiter"></div>

这里写代码片
“`

这class dog                                              
  {
      public void eat()
      {
      System.out.println("eat");
      }
      public void speak()
      {
          System.out.println("spaeak");
      }
  }
子父类出现后,类中成员的特点

类中成员包含三个部分
1、变量:如果子类中出现非私有的同名成员变量时,子类要访问本类中的变量,用this
         子类要访问父类中的同名变量,用super
          Super的使用和this的使用几乎一致。
          This代表的是本类对象的引用。
          Super代表的是父类对象的引用。

class fu
{
int num = 1;
}
class zi extends fu
{
int num = 2;

}
class extendsdemo2
{
public void main(String[] args)
{
zi z = new zi();
System.out.println(z.num+”….”+z.num);
}
}


此段代码打印的结果是什么?打印的结果为2
2、函数
这里写图片描述
此实例打印的结果为 zi show
这里写图片描述
此类调用的是子类的show方法,父类并没有运行。此方法称为覆盖(重写)。
覆盖(重写):当子类出现和父类一模一样的函数时,当子类对象调用该函数,会运行子类函数的内容,如同父类的函数被覆盖一样。这种情况是函数的另一个特性:重写(覆盖)。[父类的函数还在内存中,只是没有运行而已
]
示例:如下代码
这里写图片描述
解析:此段代码这样写编译和运行都没有任何问题,但是这样设计存在着问题。因为此时子类中有三个方法,有自身的两个方法,另外还将父类的方法继承了过来。
当子类继承父类,沿袭了父类的功能到子类中,但是子类虽具备该功能,但是功能的内容却和父类不一致;这时,没有必要定义新功能,而是使用覆盖特性,保留父类的功能定义并重写功能内容。

覆盖注意事项:
子类覆盖父类,必须保证子类权限大于等于父类权限,才可以覆盖,否则编译失败。
静态只能覆盖静态。
重载和重写的区别:
重载:只看同名函数的参数列表。
重写:子父类方法要一模一样。
3、构造函数
这里写图片描述
运行结果为:zi run; fu run
在对子类对象进行初始化时,父类的构造函数也会运行,那是因为子类的构造函数默认第一行有一条隐式的语句super();super();会访问父类中空参数的构造函数,而且子类中所有的构造函数默认第一行都是super();

为什么子类一定要访问父 类中的构造函数?
因为父类中的数据子类可以直接获取,所以子类对象再建立时,需要先查看父类是如何对这些数据进行初始化的,所以子类在对象初始化时,要先访问一下父类中的构造函数。
如果要访问父类中指定的构造函数,可以通过手动定义super语句的方式来指定。

注意:super语句一定定义在(子类)构造函数的第一行。

子类的实例化过程
结论:子类中所有的构造函数,默认都会访问父类中空参数的构造函数,因为子类每一个构造函数内的第一行都有一句隐式的super();
当父类中没有空参数的构造函数时,子类必须手动通过super语句形式来指定要访问父类中的构造函数。
当然:子类的构造函数第一行也可以手动指定this语句来访问本类中的构造函数。
子类中至少会有一个构造函数会访问父类中的构造函数。

面向对象——Final关键字
Final:最终。作为一个修饰符,final具有以下特点:
1、可以修饰类[定义为final的类不能被继承。
如果希望一个类不允许任何类继承,并且不允许其他人对这个类有任何改动,可以将这个类设置为final形式。
final类的语法如下:
final 类名{}
如果将某个类设置为final形式,则类中的所有方法都被隐式设置为final形式,但是final类中的成员变量可以被定义为final或非final形式。],函数,变量。
2、被final修饰的类不可以被继承。为了避免被继承,被子类复写功能,添加final变成最终的,变得不能被继承、被复写。
3、被final修饰的方法不能被复写。
4、被fianl修饰的变量是一个常量只能赋值一次,既可以修饰成员变量又可以修饰局部变量。
当在描述事物时,一些数据的值是固定的,为了增强阅读性,都给这些值取个名字方便阅读,而这值不需要改变,因此加上final。作为常量,常量的书写规范所有字母都大写,如果由多个单词组成,单词间通过_连接。
5、内部类[内部类包括成员内部类、局部内部类、匿名内部类和静态内部类四种][内部类的继承:内部类也和其他普通类一样可以被继承,但是继承内部类比继承普通类要复杂一些,需要设置专门的语法进行继承。][在内部类前添加修饰符static,这个内部类就变为静态内部类。一个静态内部类中可以声明static成员,但是在非静态内部类中不可以声明静态成员。静态内部类有一个最大的特点,就是不可以使用外部类的非静态成员,所以静态内部类在程序开发中比较少见。
可以这样认为,普通的内部类对象隐式地在外部保存了一个引用,指向创建它的外部类对象,但如果内部类被定义为static时,它应该具有更多的限制。静态内部类具有以下两个特点:
 创建静态内部类的对象,不需要其外部类的对象。
 不能从静态内部类的对象中访问非静态外部类的对象。][在编写程序代码时,不一定要给内部类取一个名字,可以直接以对象名来代替。匿名内部类的所有实现代码都需要在大括号之间进行编写。匿名内部类的语法如下所示:
return new A() {
…//内部类体
};
A:对象名][局部内部类就是在类的方法中定义的内部类,它的作用范围也是在这个方法体内。下面将通过一个具体的例子来说明如何定义局部内部类。][成员内部类的语法:
Public class OuterClass{//外部类
Private class Inneerclass{内部类
//
}
}在内部类中可以随意使用外部类的成员方法以及成员变量,尽管这些类成员被修饰为private。内部类的实例一定要绑定在外部类的实例上,如果从外部类中 初始化一个内部类对象,那么内部类对象就会绑定在外部类对象上。内部类初始化方式与其他类初始化方式相同,都是使用new关键字。]定义在类中的局部位置上时,只能访问该局部被final修饰的局部变量。
面向对象——多态
一:概念
1、定义:某一事物的多种存在形式。如:人有男人和女人;动物包含猫和狗等。
猫 x = new 猫(); 动物 x = new 猫();
多态性(polymorphisn)是允许你将父对象设置成为和一个或更多的他的子对象相等的技
术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。简单的说,
就是一句话:允许将子类类型的指针赋值给父类类型的指针。
2、多态的体现
父类的引用指向了自己的子类对象
父类的引用也可以接收自己的子类对象
3、多态的前提
必须是类与类之间有关系,要么继承,要么实现。
通常还有一个前提,存在覆盖。
覆盖:是指子类重新定义父类的虚函数的做法。
4、多态的好处
(1)扩展性(extensibility):多态对代码具有可扩展性。增加新的子类不影响已存在类的多态性、继承性,以及其他特性的运行和操作。实际上新加子类更容易获得多态功能。例如,在实现了圆锥、半圆锥以及半球体的多态基础上,很容易增添球体类的多态性。如图所示:
这里写图片描述
(2)可替换性(substitutability):多态对已存在代码具有可替换性。
例如,多态对圆Circle类工作,对其他任何圆形几何体,如圆环,也同样工作。如图8.1 所示。
这里写图片描述
(3)接口性(interface-ability)。多态是超类通过方法签名,向子类提供了一个共同接口,由子类来完善或者覆盖它而实现的。如图8.3 所示。图中超类Shape规定了两个实现多态的接口方法,computeArea()以及computeVolume()。子类,如Circle和Sphere为了实现多态,完善或者覆盖这两个接口方法。
这里写图片描述
(4)灵活性(flexibility)。它在应用中体现了灵活多样的操作,提高了使用效率。
(5)简化性(simplicity)。多态简化对应用软件的代码编写和修改过程,尤其在处理大量对象的运算和操作时,这个特点尤为突出和重要。
值得注意的是,多态并不能够解决提高执行速度的问题,因为它基于动态装载和地址引用,或称动态绑定。但在Java中,除了final类和一定条件下的final方法外,所有方法都由JVM在运行期间进行动态绑定。
5、多态的弊端
提高了扩展性,但是只能使用父类的引用访问父类中的成员。
6、多态的应用
由于多态性,一个父类的引用变量可以指向不同的子类对象,并且在运行时根据父类引用变量所指向对象的实际类型执行相应的子类方法。 利用多态性进行二次分发。 利用多态性设计回调方法。
补充:对象类型的转换
A:向上转型(类型提升)
因为平行四边形是特殊的四边形,也就是说平行四边形是四边形类型的一种,那么就可以将平行四边形对象看作是一个四边形对象。例如,一只鸡是家禽的一种,而家禽是动物中的一种,那么也可以将鸡对象看作是一个动物对象。
这里写图片描述
平行四边形与四边形的关系:平行四边形类继承 了四边形类,常规的继承图都是将顶级类设置在
页面的顶部,然后逐渐向下,所以将子类对象看
作是父类对象被称为“向上转型”。由于向上转
型是从一个较具体的类到较抽象的类的转,所以
它总是安全的,如可以说平行四边形是特殊的四
边形,但不能说四边形是平行四边形。
B:向下转型(强制将父类的引用转成子类类型)
通过向上转型可以推理出向下转型是将较抽象类转换为较具体的类。这样的转型通常会出现问题,例如,不能说四边形是平行四边形的一种,不能说所有的鸟都是鸽子,这非常不合乎逻辑。可以说子类对象总是父类的一个实例,但父类对象不一定是子类的实例。
注意:千万不要出现将父类对象转成子类类型。我们能转换的是父类应用指向了自己的子类对象时,该应用可以被提升,也可以被强制转换。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值