JAVA中面向对象基础:抽象类、初始化块
来源:互联网 发布:网络购物系统开题报告 编辑:程序博客网 时间:2024/06/05 15:43
本文转载连接为:http://android.yaohuiji.com/archives/3241
一、抽象类
用 abstract 修饰的类定义,我们称之为抽象类,抽象类不能被实例化。
用 abstract 修饰的方法,我们称之为抽象方法,抽象方法不能有方法体。
面向对象中,所有的对象都是某一个类的实例,但是并不是每个类都可以实例化成一个对象。如果一个类中没有足够的信息来描绘一个具体的对象,那么这个类就不能被实例化,我们称之为抽象类。抽象类用来描述一系列看起来不同,但究其本质是相同的对象。譬如把苹果、橘子、梨等抽象出来一个概念叫水果,我们把狗、老鼠、猫、狮子、大象、猪等抽象出来个概念叫动物。这时候我们把动物抽象成一个Animal类时,就最好不要让它直接初始化,创建出一个Animal()实例对象的结果似乎难以想象。
抽象类被继承之外,没有用途,没有目的。
下面我们用一个Test.java的例子看一下什么叫抽象类:
abstract class Animal {abstract void makenoise();}class Lion extends Animal {@Overridevoid makenoise() {System.out.println("狮子吼!");}}class Dog extends Animal {@Overridevoid makenoise() {System.out.println("狗叫!");}}public class Test {public static void main(String[] args){Animal a1 = new Dog();Animal a2 = new Lion();a1.makenoise();a2.makenoise();}}
编译和运行程序,我们看看结果:
这个例子里,我们有这么几点需要留意:
- 一个编译单元里是可以写多个顶级类的,只要public修饰的顶级类只有一个就行了。
- 用 abstract 修饰的类是抽象类
- 用 abstract 修饰的方法是抽象方法,抽象方法没有方法体,也就是说不能写大括号。
- 抽象类实际上是定义了一个标准和规范,等着他的子类们去实现,譬如动物这个抽象类里定义了一个发出声音的抽象方法,它就定义了一个规则,那就是谁要是动物类的子类,谁就要去实现这个抽象方法。
- 狗和狮子的类继承了动物这个抽象类,实现了发出声音的方法。
- 一个对象除了被看成自身的类的实例,也可以被看成它的超类的实例。我们把一个对象看做超类对象的做法叫做向上转型。譬如 Animal a1 = new Dog();
- 虽然都是动物类型,但是方法在运行时是按照它本身的实际类型来执行操作的。因此 a1.makenoise()执行的是狗叫,a2.makenoise()执行的是狮子吼,我们称之为运行时多态。
我们再看一下把一个类看做一个超类有什么样的损失或者不便,我们把上面的例子稍微改一下:
abstract class Animal {abstract void makenoise();}class Lion extends Animal {@Overridevoid makenoise() {System.out.println("狮子吼!");}}class Dog extends Animal {@Overridevoid makenoise() {System.out.println("狗叫!");}void bark(){System.out.println("汪,汪!");}}public class Test {public static void main(String[] args){Animal a1 = new Dog();Animal a2 = new Lion();a1.makenoise();a2.makenoise();((Dog)a1).bark();}}运行程序,查看结果:
我们把焦点放在第35行,我们再a1前面加了一个(Dog),这个做法的意思是把a1强制转换为Dog对象,只有转换为Dog对象后,才能使用bark方法,否则即使你知道他是一个Dog对象也不能调用bark方法。这就是子类对象付给超类引用所带来的不便或者说是损失。
二、初始化块
我们已经知道在类中有两个位置可以放置执行操作的代码,这两个位置是方法和构造函数。初始化块是第三个可以放置执行操作的位置。当首次加载类(静态初始化块)或者创建一个实例(实例初始化块)时,就会运行初始化块。
我们看一个例子:
class SuperClass{SuperClass(){System.out.println("父类SuperClass的构造函数");}}public class Initialize extends SuperClass {Initialize(int x){System.out.println("带参数的构造函数");}Initialize(){System.out.println("不带参数的构造函数");}static {System.out.println("第一个静态初始化块");}{System.out.println("第一个实例初始化块");}{System.out.println("第二个实例初始化块");}static {System.out.println("第二个静态初始化块");}public static void main(String[] args){new Initialize(1);new Initialize();}}编译并运行程序,查看结果:
从上面的例子中我们需要留意如下几点:
- 初始化块的语法相当简单,它没有名称,没有参数,也没有返回值,只有一个大括号。用 static 修饰的初始化块就要静态初始化块,相对应的,没有static修饰的初始化块就叫实例初始化块。
- 静态初始化块在首次加载类时会运行一次。
- 实例初始化块在每次创建对象时会运行一次。
- 实例初始化块在构造函数的super()调用之后运行。
- 初始化块之间的运行顺序取决于他们在类文件中出现的顺序,出现在前面的先执行。
- 初始化块从书写惯例上应该写在靠近类文件的顶部,构造函数附近的某个位置。
- JAVA中面向对象基础:抽象类、初始化块
- [疯狂Java]面向对象:初始化块、初始化代码、初始化顺序
- 面向对象--初始化块
- 【Java基础】——java面向对象(中)—继承、抽象类、接口
- Java面向对象基础--代码块
- Java基础学习中,关于面向对象中多态、抽象类、接口的总结
- 黑马程序员---Java基础---面向对象:继承、抽象类、接口
- java基础-面向对象(接口和抽象类)
- Java基础--面向对象(继承、抽象类、接口)
- java基础--3.面向对象-5.抽象类和接口
- java基础总结15-面向对象11(抽象类)
- JAVA面向对象-----抽象类
- Java面向对象-抽象类
- Java基础(一):Java面向对象、面向对象封装、抽象类、接口、static、final
- Java基础(一):Java面向对象、面向对象封装、抽象类、接口、static、final
- java基础---初始化块
- Java基础2面向对象:透析类的加载与初始化 对象的初始化 zongjihengfei
- java面向对象中抽象类的使用方法
- 2011年SSCI收录信息科学与图书馆学学科期刊86种
- MIPS地址空间
- JSP工程小结
- dw 使用手机模拟器环境
- (转)关于 Debug 和 Release 版本区别
- JAVA中面向对象基础:抽象类、初始化块
- ubuntu 设置中文编码
- C++ string对象读文件
- 随机算法和概率分析的区别
- linux中一个通过管道读取大量数据的程序源代码
- 代码测试之代码调试
- freemarker 字符串函数 .
- 如何获取和设置android系统铃声和音量大小
- JSP与Servlet的连通