java基础——面向对象(二)

来源:互联网 发布:php为什么比aps.net好 编辑:程序博客网 时间:2024/06/07 18:48

                        第三讲  继承

一、概念

  多个类中存在相同的属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继承那个类即可

   多个类可以称之为子类,单独这个类称为父类,或超类

   子类可以直接访问父类中非私有的属性和行为

extends关键字

通过extends关键字让类与类之间产生继承关系

 

继承的出现,提高了代码的复用性,继承的出现让类与类之间产生了关系,提供了多态的前提

 

注意:子类不可以具有父类中私有的内容

父类是怎么来的呢?是向上不断抽取而来的

什么时候定义继承呢?

必须保证类与类之间有所属,即:xxxzzz中的一类

 

特点:

java允许单继承,不直接支持多继承,将多继承进行其他方式的体现

单继承:一个子类只能继承一个父类

多继承:一个子类可以有多个父类,但是多继承调用可能出现不确定性,所以java保留了多继承的好处,改良了它弊端,用多实现来体现

 

java还支持多重继承

class A{}

class B{} extends A

class C{} extends B

形成继承体系

学习继承体系是,应该参阅顶层类中的内容

了解这个体系的基本功能

使用这个体系的基本功能,需要创建最子类的对象

 

二、继承出现后,在代码中的体现

重点在于成员的体现

1、成员变量

   特殊情况:子父类中定义了一摸一样的成员变量,都存在于子类对象中

   如何在子类中直接访问同名父类中的变量呢?通过关键字super来完成

superthis很像

this:代表的是本类的对象的引用。
super
:代表的是父类的内存空间。


注意:这种情况开发见不到,因为父类一旦描述完了属性,子类直接使用就可以了。

 

2、成员函数

【子父类中成员函数的特点】
特殊情况:
子父类中的定义了一模一样的函数。
运行的结果:子类的函数在运行。
这种情况在子父类中,是函数的另一个特性:override(重写,覆盖,复写)

 

随着电话的升级,只显示号码不爽,希望显示姓名,大头贴。
修改源码,虽然费劲但是可以解决,不利于后期的维护和扩展。
为了扩展方便。新功能是不是新的电话具备呢?
单独描述单独封装。新电话也是电话中的一种。继承。直接获取父类中的功能。
但是新电话的来显功能已经变化了。需要重新定义。
那么定义一个新功能合适吗?比如newShow,不合适,因为父类已经将来显功能定义完了,
子类完全不需要重新定义新功能。直接用就可以了。如果子类的来显功能内容不同。
直需要保留来显功能,定义子类的内容即可:这就是重写的应用!

 

【重写(覆盖)的注意事项】


1
,子类覆盖父类,必须保证全要大于或者等于父类的权限。
Fu:
private void show(){}


Zi:
public void show(){}
2
,静态覆盖静态。


写法上稍微注意:必须一模一样:函数的返回值类型函数名参数列表都要一样。


【总结】
当一个类是另一个类中的一种时,可以通过继承,来扩展功能。
如果从父类具备的功能内容需要子类特殊定义时,使用重写。

 

3、构造函数

【子父类中构造函数的特点】
当子父类都有构造函数时,发现结果为:
fu constructor run
zi constructor run
先执行了父类的构造函数,再执行子类的构造函数。


【这是为啥呢?】
因为子类的所有的构造函数中的第一行都有一句隐式语句super(); //默认调用的是父类中的空参数的构造函数。


【子类中的构造函数为什么有一句隐式的super()呢?】
原因:子类会继承父类中的内容,所以子类在初始化时,必须先到父类中去执行父类的初始化动作。
才可以更方便的使用父类中的内容。


【小结】
当父类中没有空参数构造函数时,子类的构造函数必须同构显示的super语句指定要访问的父类中的构造函数。
这就是传说中的子类实例化过程。


【实例化过程的细节】
1
,如果子类的构造函数第一行写了this调用了本类其他构造函数,那么super调用父类的语句还有吗?
没有的,因为this()或者super(),只能定义在构造函数的第一行,因为初始化动作要先执行。


2
,父类构造函数中是否有隐式的super呢?
也是有的。记住:只要是构造函数默认第一行都是super();
父类的父类是谁呢?super调用的到底是谁的构造函数呢?
Java
体系在设计,定义了一个所有对象的父类Object


【总结】
类中的构造函数默认第一行都有隐式的super()语句,在访问父类中的构造函数。
所以父类的构造函数既可以给自己的对象初始化,也可以给自己的子类对象初始化。

如果默认的隐式super语句没有对应的构造函数,必须在构造函数中通过this或者super的形式明确调用的构造函数。


【问题】
1
this语句和super语句是否可以在同一个构造函数中出现呢?不行,因为必须定义在第一行。
2
,为什么要定义在第一行呢?因为初始化动作要先执行。

 

细节:

1、如果子类的构造函数第一行写了this调用了本类其他构造函数,那么super调用父类的语句还有吗?

   没有了,因为this()或super()只能定义在构造函数的第一行,因为初始化动作要先执行

2、父类构造函数中是否有隐式super呢?

   有的,只要是构造函数,默认第一行都是super;父类的父类是谁呢?super调用的到底是谁的构造函数呢?

java体系在设计时,定义了一个所有对象的父类Object

 

总结:

类中的构造函数默认第一行都有隐式super语句,在访问父类的构造函数

所以,父类的构造函数既可以给自己的对象初始化,也可以给子类的对象进行初始化

如果默认的隐式super的语句没有对应的构造函数,必须在构造函数中通过this或者super的形式明确调用的构造函数

子类实例化过程的应用。也是super调用的应用

什么时候用super调用父类中的构造函数呢。只要使用父类的指定初始化动作,就在子类中通过super(参数列表)格式进行调用

 

final关键字

继承的弊端:破坏了封装性(重写)

不让其他类继承该类,就不会重写

可以通过java中的一个关键字final来实现,final是一个修饰符,可以修饰类,方法,变量(成员变量,局部变量,静态变量)

特点:

1final修饰的类是一个最终类,不能派生子类,如果类中出现部分可以重写,部分不可以重写怎么办?

   只要让制定的方法最终化即可

2final修饰的方法是最终方法,不可以重写

3final修饰的变量时一个常量,只能被赋值一次

什么时候会在程序中定义final常量呢?

当程序中一个数据使用时是固定不变的,这时为了增加阅读性,可以给该数据起个名字,这就是变量,为了保证这个变量的值不被修改,加上final修饰,这就是一个阅读性很强的常量

 

抽象类概述

定义:抽象就是从多个事物中将共性的,本质的内容抽取出来

例如:狼和狗都属于犬科,犬科就是抽象出来的概念

抽象类:

java中可以定义没有方法体的方法,该方法的具体实现由子类完成,该方法称为抽象方法,包含该方法的类就称为抽象类

抽象类的特点:

抽象类和抽象方法必须用abstract关键字来修饰

抽象方法只有方法声明,没有方法主体,定义在抽象类中

格式:修饰符abstract返回值类型函数名(参数列表);

抽象函数:需要abstract修饰,并结束

抽象类不可以被实例化,也就是不可以用new创建对象

原因如下:

1、抽象类是具体事物抽取出来的,本身不是具体的,没有对应的实例

2、而且抽象类即使创建了对象,调用抽象方法也没有意义

 

抽象类通过其子类实例化,而子类需要覆盖抽象类中所有抽象方法后才可以创建对象,否则该子类也是抽象类

 

之所以继承,更多的是思想,是面对共性类型操作会更简单

 

细节:

1、抽象类是一个父类,因为抽象类是不断向上抽取而成

2、抽象类是否有构造函数?

   有的,因为虽然不能给自己初始化,但是可以给子类初始化

抽象类和一般类的异同点:

相同:a、他们都是用来描述事物的。b、都可以定义属性和行为

不同:a、一般类可以具体的描述事物,抽象类描述事物的信息不具体

   b、抽象类可以多定义一个成员,抽象函数

   c、一般类可以创建对象,而抽象类不可以创建对象,必须通过子类来完成

3、抽象类中是否可以不定义抽象方法?

   可以的,那这个抽象类的存在有何意义?仅仅是不让该类创建对象

4、抽象关键字abstract不可以和以下关键字共存

afinal//final修饰的类不可以派生子类,而抽象类必须有子类

bprivate//抽象方法必须被覆盖,加上private后就无法被覆盖

cstatic//静态可以被类名调用,但是抽象类被类名调用无意义

 

interface(接口)关键字

抽象类中可以定义抽象方法的

当一个抽象类中的方法全是抽象的

这时,可以通过另一种特殊的形式类实现——接口

 

接口中的成员已经被限定为固定的几种

接口的定义格式先介绍两种:

1、定义变量;但是变量必须有固定的修饰符修饰:public static final,所以接口中的变量也称为常量

2、定义方法;方法也有固定的修饰符:public abstract,接口中的成员都是公共的

 

接口的特点:

1、接口不可创建对象

2、子类必须覆盖掉接口中所有抽象方法后,子类才可以实例化,否则子类就是一个抽象类

 

接口最重要的体现

解决多继承的弊端,将多继承这种机制在java中通过多实现完成了

 

          第四讲  多态

【体现】
     
父类的引用或者接口的引用指向了自己的子类对象。
     
Dogd = new Dog();//Dog对象的类型是Dog类型。
     
Animala = new Dog();//Dog对象的类型右边是Dog类型,左边Animal类型。

【好处】
  
提高了程序的扩展性。
【弊端】
  
通过父类引用操作子类对象时,只能使用父类中已有的方法,不能操作子类特有的方法。
【前提】
  
1,必须有关系:继承,实现。
  
2,通常都有重写操作。
【子类的特有方法如何调用呢?】
  
Animala = new Dog();//Animal是父类型,new Dog()是子对象。
  
但是父类型引用指向子类对象时,这就是让子类对象进行了类型的提升(向上转型)
  
向上转型好处:提高了扩展性,隐藏了子类型。弊端:不能使用子类型的特有方法。
  
如果要想使用子类的特有方法,只有子类型可以用。
  
可以向下转型,强制转换。
  
Animala = new Dog();
   a.eat();
   Dog d= (Dog)a;//a转型为Dog类型。向下转型。
  
d.lookHome();
   向下转型什么时候用?当需要使用子类型的特有内容时。
  

   注意:无论向上还是向下转型,最终都是子类对象做着类型的变化。
  

   【向下转型的注意事项】
  
Animala = new Dog();
   //Catc = (Cat)a;向下转型因为不明确具体子类对象类型,所以容易引发ClassCastException异常。
  
所以为了避免这个问题,需要在向下转型前,做类型的判断。
  
判断类型用的是关键字instanceof

多态中,成员调用的特点。


1
,成员变量。
  
当子父类中出现同名的成员变量时。
     
多态调用该变量时:
       
编译时期:参考的是引用型变量所属的类中是否有被调用的成员变量。没有,编译失败。
       
运行时期:也是调用引用型变量所属的类中的成员变量。
     
简单记:编译和运行都参考等号的左边。
          
编译运行看左边。


2
,成员函数。
  
编译,参考左边,如果没有,编译失败。
  
运行,参考右边的对象所属的类。
     
编译看左边,运行看右边。
  

   对于成员函数是动态绑定到对象上。


3
,静态函数。
  
编译和运行都参考左边。


  
静态函数是静态的绑定到类上。


【结论】
对于成员变量和静态函数,编译和运行都看左边。
对于成员函数,编译看左边,运行看右边。


内部类

当A类中的内容要被B类访问,而A类还需要创建B类对象,访问B类内容时,可将B类定义到A类内部,这样访问更为便捷,将B类称为内部类

访问方式:
内部类可以直接访问外部类中的所有成员,包含私有的。
而外部类要想访问内部类中的成员,必须创建内部类的对象。


当描述事物时,事物的内部还有事物,这个内部的事物还在访问外部事物中的内容。
这时就将这个事物通过内部类来描述。


为什么内部类就能直接访问外部类中的成员呢?
那是因为内部类其实持有了外部类的引用  外部类.this 
对于静态内部类不持有 外部类.this  而是直接使用 外部类名。



【内部类被访问的方式】
情况一:内部类在成员位置上的被访问方式。
成员是可以被指定的修饰符所修饰的。
public:不多见:因为更多的时候,内部类已经被封装到了外部类中,不直接对外提供。
static: 

内部类其实也可以定义在外部类的局部位置上。


内部类定义在局部时,只能访问被final修饰的局部变量。
为啥呢?因为编译生产的class中直接操作那个最终数值了。


为什么不能访问非最终的局部变量呢?


内部类的延伸
内部类是可以继承或者实现外部其他的类或者接口的。


好处:通过内部类的方式对类进行继承重写,或者接口进行实现。
通过公共的方式对其内部类对象进行访问。因为通常内部类很有可能被外部类封装其中。
我们就可以通过父类或者接口的方式访问到内部类对象。


匿名内部类

其实就是一个带有内容的子类对象。
格式:new 父类or接口(){子类的内容}
匿名内部类就是内部类的简化形式。
别忘了:匿名内部类有前提,内部类必须要继承父类或者实现接口




————————————————————————————————————————————————----—


小结:本版内容主要是讲了java中的三大思想:封装、继承、多态;个人理解,学习语言,思想最重要,这个要深入理解,重点掌握



 



0 0
原创粉丝点击