本文转载连接为: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();}
}

编译和运行程序,我们看看结果:

这个例子里,我们有这么几点需要留意:

  1. 一个编译单元里是可以写多个顶级类的,只要public修饰的顶级类只有一个就行了。
  2. 用 abstract 修饰的类是抽象类
  3. 用 abstract 修饰的方法是抽象方法,抽象方法没有方法体,也就是说不能写大括号。
  4. 抽象类实际上是定义了一个标准和规范,等着他的子类们去实现,譬如动物这个抽象类里定义了一个发出声音的抽象方法,它就定义了一个规则,那就是谁要是动物类的子类,谁就要去实现这个抽象方法。
  5. 狗和狮子的类继承了动物这个抽象类,实现了发出声音的方法。
  6. 一个对象除了被看成自身的类的实例,也可以被看成它的超类的实例。我们把一个对象看做超类对象的做法叫做向上转型。譬如 Animal a1 = new Dog();
  7. 虽然都是动物类型,但是方法在运行时是按照它本身的实际类型来执行操作的。因此 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();}
}

编译并运行程序,查看结果:

从上面的例子中我们需要留意如下几点:

  1. 初始化块的语法相当简单,它没有名称,没有参数,也没有返回值,只有一个大括号。用 static 修饰的初始化块就要静态初始化块,相对应的,没有static修饰的初始化块就叫实例初始化块。
  2. 静态初始化块在首次加载类时会运行一次。
  3. 实例初始化块在每次创建对象时会运行一次。
  4. 实例初始化块在构造函数的super()调用之后运行。
  5. 初始化块之间的运行顺序取决于他们在类文件中出现的顺序,出现在前面的先执行。
  6. 初始化块从书写惯例上应该写在靠近类文件的顶部,构造函数附近的某个位置。

JAVA中面向对象基础:抽象类、初始化块相关推荐

  1. 8.java中面向对象---基础概念(1)(附讲解与练习)

    学习面向对象内容的三条主线 1.Java类及类的成员 属性,方法,构造器,代码块,内部块 2.面向对象的三大特征 封装 (Encapsulation) 继承 (Inheritance) 多态 ( ...

  2. Java中接口、抽象类与内部类学习

    2019独角兽企业重金招聘Python工程师标准>>> Java中接口.抽象类与内部类学习 接口与内部类为我们提供了一种将接口与实现分离的更加结构化的方法. 抽象类和抽象方法 抽象方 ...

  3. 【Java练习题汇总】《第一行代码JAVA》面向对象基础篇,汇总Java练习题——面向对象:特性、类与对象、数组、String、内部类... ~

    Java练习题 · 面向对象基础篇 1️⃣ 面向对象基础篇 1️⃣ 面向对象基础篇 一.填空题 面向对象的三大特征:_______ ._______ ._______. 类由_______和_____ ...

  4. java integer最大值_五分钟学会java中的基础类型封装类

    在刚刚学习java的时候,老师不止一次的说过java是一种面向对象的语言,万物皆对象.对于java中的基础数据类型,由于为了符合java中面向对象的特点,同样也有其封装类.这篇文章对其有一个认识. 一 ...

  5. java中的四种代码块

    原文链接: java中的四种代码块_Munt的博客-CSDN博客_java中代码块 在java中用{}括起来的称为代码块,代码块可分为以下四种: 一.简介 1.普通代码块: 类中方法的方法体 2.构造 ...

  6. java全局变量初始化_为什么 Java 中全局变量不一定初始化,局部变量必须初始化?...

    前几天,有个大佬考了我一个问题:为什么类的成员变量不需要指定值就可以自动赋予初始值,而方法内的局部变量就必须指定初始值呢? 说实话,这个问题确实难倒我了,之后我在网上一顿操作,终于把这个问题弄得稍微明 ...

  7. java 代码块_详解java中的四种代码块

    在java中用{}括起来的称为代码块,代码块可分为以下四种: 一.简介 1.普通代码块: 类中方法的方法体 2.构造代码块: 构造块会在创建对象时被调用,每次创建时都会被调用,优先于类构造函数执行. ...

  8. Java中面向对象三大特征总结

    JAVA中面向对象的三大特征: 面向对象具有继承性(Inheritance) 面向对象具有多态性(Polymorphism) 面向对象具有封装性(Encapsulation) 一.继承 多个类具有共同 ...

  9. 关于Java静态成员变量和静态初始化块等的初始化顺序的详细介绍

    关于Java静态成员变量和静态初始化块等的初始化顺序的详细介绍 对于主动请求一个类时,JVM首先会将该类加载到内存中,先初始化该类的静态成员变量和静态初始化块. 主动请求一个类的情形: a.调用类A的 ...

最新文章

  1. 58. Length of Last Word
  2. 调链接_古筝谱 |踏山河是七叔呢演唱歌曲 双手版 D调 简谱唱谱
  3. FragmentPagerAdapter实现刷新
  4. Python 3.8 新功能大揭秘
  5. phpstudy之解决phpmyadmin卡顿的方法
  6. 2017年第八届C/C++ B组蓝桥杯省赛真题
  7. 微信公众号授权 提示内容与下载文件不符,请检查文件内容或重新上传
  8. 批量制作学校图书馆条码标签
  9. 微软Kinect:谁还要控制器?
  10. 使用 JMeter的性能测试
  11. 教你如何免费下载浏览器上收费的音乐和视频
  12. (Arduino)蓝牙和 APPinventor实现一键SOS求救(一)
  13. Calendar代替Date类获取当前年月日,getYear,getMonth,getDay
  14. apktool安装过程
  15. CAD 偏移和复制、移动的区别
  16. 数据脱敏小探——数据脱敏技术概述
  17. K8s——kubernetes集群中ceph集群使用【上】
  18. SpringCloud采用Jackson序列化统一响应不正当的消息转换器导致的异常问题
  19. 关于使用不同单片机 工程报错总结(STC12C5A60S2)
  20. linux下的gedit命令使用方法与技巧

热门文章

  1. java lists.aslist_java Arrays.asList()
  2. 人人应该知晓的外国典故
  3. 哪种主机更适合初创公司租用?云主机与共享主机
  4. php 微信上传多图片不显示不出来,php - 微信群发图文,content中图片显示不出
  5. 音乐怎么发在计算机里,音乐伴奏怎么发送到微信、电脑、手机、U盘?
  6. java获取系统时间到毫秒_java获取当前时间精确到毫秒
  7. 将scss文件转换成css文件
  8. 蓝桥杯复习笔记20180304
  9. 【JavaScript】 sort排序
  10. 【新手指南】Python中的listdir()函数的介绍