可以为一个变异单元中的每个类创建一个main方法,只有命令行所调用的那个类的main方法才会被调用,这样方便进行单元测试。
继承时,一般将所有的数据成员都指定为private,将所有的方法指定为public。
当创建一个子类的对象时,该对象内部包含了一个父类的子对象(subobject??)。这个对象和用父类直接创建的对象是一样的。
关键字super并不是一个对象的引用,因为不能将super赋值给另外一个对象变量。super只是一个只是编译器调用直接父类成员变量的特殊关键字。有两种用途:一是调用父类的方法;二是调用父类的构造器。
如果父类构造器为无参构造器,子类构造器中可以不用写调用父类构造器的语句,编译器会自动加上。但是如果父类构造器有参数时,在子类构造器中必须显式的通过super(arg)调用父类的构造器,否则会报错。
子类可以override父类方法,也可以overload父类的方法。
所有的override都使用@Override注解,可以防止不想重载时而意外的进行了重载。
重写(Override)
重写是子类对父类允许访问的方法的实现过程进行重新编写。好处在于子类可以根据需要,定义特定于自己的行为。
当父类中的方法被覆盖了后,除非用super关键字,否则就无法再调用父类中的方法。
重写规则:两同两小一大。
方法名、参数列表必须相同;返回值类型和抛出的异常更小或相等;访问权限更大或相等。
声明为final的方法不能被重写;
声明为static的方法不能被重写,但是能够被再次声明;
重写的方法能够抛出任何非强制异常,不能抛出新的或更广泛的强制性异常;
构造方法不能被重写;
父类的成员方法只能被它的子类重写,如果不能继承一个方法,则不能重写这个方法;
子类和父类在同一个包中,声明为private和final的方法不可被子类重写;
子类和父类不在同一个包中,子类只能重写父类的声明为public和protected的非final方法;
被覆盖的方法不能为static,因为静态方法是在编译的时候把静态方法和类的引用类型进行匹配。

组合和继承
组合是”has-a”的关系,在新类中嵌入一个现有类的private对象,新类的用户看到的是为新类所定义的接口,而不能看到嵌入对象的方法。
extend关键字的英文意思是扩展,表明子类对父类的扩展,子类是一种特殊的父类。
继承是”is-a”的关系,使用某个现有类,并开发一个它的特殊版本。通常使用的场景:
  1. 子类需要额外增加属性,而不仅仅是属性值的改变。
  2. 子类需要增加自己独有的行为方式(包括增加新的方法或重写父类的方法)。
只有必须向上转型时才用继承,否则优先考虑使用组合。

向上转型
为什么需要?
子类不仅是子类的类型,而且也是父类的类型。向上转型是从一个较专用类型向较通用类型转换,一般比较安全,唯一可能反生的事情是接口变小丢失子类对父类扩展的方法。因为编译期虚拟机会预先为每个类生成方法表(父类不会具有子类的方法,但是子类会具有父类的方法),向上造型的引用变量调用子类特有的方法,会报错。

final关键字:一旦(在初始化过程中)被设置为初始值之后,就不能再改变。

final数据:static final编译时期常量,全用大写字母表示,单词间用下划线’_’分割。

  对于基本类型,final使数字恒定不变;而对于对象引用,final使引用恒定不变,但引用的对象可以发生改变。

  空白final:被声明为final但又未给定初值的成员变量。需确保在使用前初始化。

  final参数:无法在方法中更改参数引用所指向的对象。

  final方法:确保在继承中方法行为保持不变,并且不会被覆盖或修改。

类中所有的 private 方法都隐式地是 final 的。

final类:不允许做任何变动,没有子类,所以方法也隐式地为final的。

不可变类(immutable):创建该类的实例之后,该实例的属性是不可变的。如果不可变类包含引用类型的属性,可以在内部重新构建一个一模一样的对象赋值给引用,使引用脱离外部影响。

多态
相同类型的父类引用变量,执行同一个方法时呈现出不同的行为,这就是多态。
“封装”通过合并特征和行为来创建新的数据类型。“实现隐藏”则通过细节私有化将接口和实现分离开来。而多态的作用则是消除类型之间的耦合关系,将多种子类型视为同一父类型进行处理(父类型的引用变量可以引用不同子类型的对象),这样同一份代码可以毫无差别地运行在这些不同子类型上,不用为每一个子类型重复定义相同逻辑的处理方法。
多态用父类型引用调用相应的方法,如何确定是哪个具体子类型呢?
绑定指的是将一个方法的调用与方法的主体关联起来java中,绑定分为静态绑定和动态绑定(dynamic binding),或者叫做前期绑定(early binding)和后期绑定(late binding)。

静态绑定:在程序执行前方法已经被绑定(也就是说在编译过程中就已经知道这个方法到底是哪个类中),此时由编译器或其它连接程序实现。

在java中可以简单理解为程序编译期的绑定,只有被final,static,private修饰的方法和构造方法是前期绑定的,由声明的类型决定。
java的编译过程是将java源文件编译成字节码(jvm可执行代码,即.class文件)的过程,在这个过程中java是不与内存打交道的,编译器会进行语法的分析,如果语法不正确就会报错(比如编译器只允许对象调用在类中声明的函数)。
Java的运行过程是指jvm(java虚拟机)装载字节码文件并解释执行,在这个过程才创立内存空间,执行java程序。

动态绑定:在运行时根据对象的类型进行绑定。之所以存在动态绑定,就是因为有些方法需要实例化对象后才能确定是哪个类的。
若一种语言实现了后期绑定,必须提供一些机制,可在运行期间判断对象的类型,并分别调用适当的方法。也就是说,编译器一直不知道对象的类型,但方法调用机制能找到正确的方法主体并加以调用。
动态绑定的过程:
虚拟机提取对象的实际类型的方法表(虚拟机预先为每个类创建的表,列出了所有方法的签名,以后方法调用时就无需搜索,只要查表就性);虚拟机搜索方法签名;调用方法。
动态绑定的特性:无需对现存的方法代码进行重新编译就可以对程序进行扩展。
动态绑定的典型发生在父类和子类的转换声明之下:Parent p = new Child();
注意:运行时(动态)绑定针对的范畴只是对象的方法,类中的成员变量(实例变量和类变量)是一般意义上的静态绑定,由编译器解析,只能访问引用变量类型所具有的属性。所以在向上转型后,父类的引用调用哪个子类型的方法由子类型对象决定,而访问对象属性时,系统总是访问它编译时类所定义的属性,即由向上造型后的父类型引用决定(子类对父类成员变量的隐藏)。
重载的方法签名是完全不同的,所以静态绑定就可以确定到底是哪个方法了;而重写的方法签名是可以和超类一样的,需要实例化对象之后才能确定是哪个类中的方法。
super.getClass().getName() //返回当前子类的类名

package demo3;
class Super {
public int field = 0;
public int getField() {
return field;
}
} class Sub extends Super {
public int field = 1;
public int getField() {
return field;
}
public int getSuperField() {
return super.field;
}
} public class FieldAccess {
public static void main(String[] args) {
Super sup = new Sub(); // Upcast
System.out.println("sup.field = " + sup.field + ", sup.getField() = " + sup.getField());
Sub sub = new Sub();
System.out.println("sub.field = " + sub.field + ", sub.getField() = " + sub.getField()+ ", sub.getSuperField() = " + sub.getSuperField());
}
}
/*
* Output: sup.field = 0, sup.getField() = 1 sub.field = 1, sub.getField() = 1,
* sub.getSuperField() = 0
*/// :~

向下转型
父类型的引用变量转向更具体的子类型,不安全,有可能会导致ClassCastExecption。转型之前先用instanceof 关键字判断一下。
instanceof:is a runtime check,判断前者引用变量是否是后者实现类或接口的实例,通常instanceof前后的操作数有实现或继承关系,否则在编译时就会出错,而不会等运行时再返回false,效率更高。
new Date() instanceof String;// Incompatible conditional operand types Date and String

super和this的区别
1)super(参数):子类调用父类的某一个构造函数(应该为子类构造函数中的第一条语句)
2)this(参数):调用本类中重载的构造函数(应该为构造函数中的第一条语句)
3)super: 基类与派生类中有相同成员定义时,用来访问当前对象的直接父类中的成员(即访问直接父类中被隐藏/覆盖的成员数据或方法)。如:super.属性名,super.方法名。
4)this:它代表当前对象的引用(如果函数的形参与类的属性同名,这时需用this来指明对象的属性)
5)调用super()必须写在子类构造方法的第一行,否则编译不通过。每个子类构造方法的第一条语句,都是隐含地调用super()。
6)尽管可以用this调用一个构造器,但却不能调用两个。
7)this和super不能同时出现在一个构造函数里面,因为this必然会调用其它的构造函数,其它的构造函数必然也会有super语句的存在,所以在同一个构造函数里面有相同的语句,就失去了语句的意义,编译器也不会通过。
8)this()和super()都指的是对象,所以都不可以在static环境中使用。包括static变量,static方法和static语句块。
9)从本质上讲,this是一个指向本对象的指针, 然而super是一个Java关键字。

java面向对象--继承与多态的更多相关文章

  1. Java面向对象㈡ -- 继承与多态

    Java的继承是通过extends和implement来实现的,Java不支持多继承,但是Java支持多层继承以及多实现(接口).Java继承有一个关键字super是用来指向父类.Java继承衍生出覆 ...

  2. Java面向对象 继承(下)

     Java面向对象   继承(下) 知识概要:               (1)抽象类 1.1 抽象类概述                            1.2 抽象类的特点       ...

  3. Java面向对象 继承(上)

       Java面向对象 继承 知识概要:         (1)继承的概述 (2)继承的特点 (3)super关键字 (4)函数覆盖 (5) 子类的实例化过程 (6) final关键字 (1)继承 ...

  4. Java的继承和多态

    看了博客园里面的一个文章,关于java的继承和多态: class A ...{ public String show(D obj)...{ return ("A and D"); ...

  5. [转]Java中继承、多态、重载和重写介绍

    什么是多态?它的实现机制是什么呢?重载和重写的区别在那里?这就是这一次我们要回顾的四个十分重要的概念:继承.多态.重载和重写. 继承(inheritance) 简单的说,继承就是在一个现有类型的基础上 ...

  6. [ Java学习基础 ] Java的继承与多态

    看到自己写的东西(4.22的随笔[ Java学习基础 ] Java构造函数)第一次达到阅读100+的成就还是挺欣慰的,感谢大家的支持!希望以后能继续和大家共同学习,共同努力,一起进步!共勉! ---- ...

  7. java中继承和多态的理解

    继承的概念 继承是java面向对象编程技术的一块基石,因为它允许创建分等级层次的类. 继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父 ...

  8. JAVA 面向对象中的多态

    多态是继封装.继承之后,面向对象的第三大特性. 现实事物经常会体现出多种形态,如学生,学生是人的一种,则一个具体的同学张三既是学生也是人,即出现两种形态. Java作为面向对象的语言,同样可以描述一个 ...

  9. Java基础——继承和多态

    面向对象的编程允许从已经存在的类中定义新的类,这称为继承. 面向过程的范式重点在于方法的设计,而面向对象的范式将数据和方法结合在对象中.面向对象范式的软件设计着重于对象以及对象上的操作.面向对象的方法 ...

随机推荐

  1. 4月5日--课堂笔记--JS内置对象

    JavaScript 4.5 一.    JS内置对象 1.数组Array a)创建语法1:var arr=new Array(参数); i.       没有参数:创建一个初始容量为0的数组 ii. ...

  2. 理解C++中的头文件和源文件的作用【转】

    一.C++编译模式通常,在一个C++程序中,只包含两类文件--.cpp文件和.h文件.其中,.cpp文件被称作C++源文件,里面放的都是C++的源代码:而.h文件则被称作C++头文件,里面放的也是C+ ...

  3. dd命令的使用简介

    dd命令: convert and copy a file 用法:  dd if=/PATH/FROM/SRC of=/PATH/TO/DEST   bs=#: block size, 复制单元大小  ...

  4. ios 苹果手机硬件摘要

    IPhone4 * 2010年发布. * A4单核处理器. * 3.5英寸Retina显示屏(视网膜屏幕),960x640像素分辨率. * 后置摄像头500万像素. * 前置摄像头30万像素. IPh ...

  5. 在c++中,标准输入string时cin 与getline两个函数之间的区别

    cin: cin函数是标准库的输入函数,在读取string时遵循以下规则: 1)读取并忽略开头所有的空白符(包括空格.换行符.制表符). 2)读取字符直到遇到空白符,读取终止. 例如: 当输入的是“  ...

  6. IEnumerable<T>和IQueryable<T>

    建议29.区别LINQ查询中的IEnumerable<T>和IQueryable<T> LINQ查询方法一共提供了两类扩展方法,在System.Linq命名空间下,有两个静态类 ...

  7. Linux - 进程调度算法

    进程调度: 无论是在批处理系统还是分时系统中,用户进程数一般都多于处理机数.这将导致它们互相争夺处理机.另外,系统进程也同样需要使用处理机. 这就要求进程调度程序按一定的策略,动态地把处理机分配给处于 ...

  8. XISE菜刀V21.0 官网版 XISE菜刀VIP破解版 XISE官网

    诠释: 1. 破解VIP登陆限制 2.去后门 (自查) 下载地址 : https://pan.baidu.com/s/1skUqlGD https://pan点baidu点com/s/1skUqlGD ...

  9. RabbitMQ基础

    上一博客把RabbitMQ的安装配置介绍了下,今天主要是介绍下RabbitMQ的一些基础名词. 一.什么是RabbitMQ?用它能做什么? 1.简介 AMQP,即Advanced Message Qu ...

  10. Lucene工作原理

    Lucene是一个高性能的java全文检索工具包,它使用的是倒排文件索引结构.该结构及相应的生成算法如下: 0)设有两篇文章1和2 文章1的内容为:Tom lives in Guangzhou,I l ...