方法重写、方法重载
方法重写概述
子类中出现了和父类中一模一样的方法声明,也被称为方法覆盖,方法复写。
方法重载概述
本类中出现的方法名一样,参数列表不同的方法。与返回值无关。
使用特点:
如果方法名不同,就调用对应的方法
如果方法名相同,最终使用的是子类自己的
方法重写的应用:
当子类需要父类的功能,而功能主体子类有自己特有内容时,可以重写父类中的方法,这样,即沿袭了父类的功能,又定义了子类特有的内容。
方法重写的注意事项
A:父类中私有方法不能被重写(因为父类私有方法子类根本就无法继承)
B:子类重写父类方法时(访问权限不能更低,最好就一致)
C:父类静态方法,子类也必须通过静态方法进行重写
子类重写父类方法的时候,最好声明一模一样。
方法重写(Override)和方法重载(Overload)的区别?方法重载能改变返回值类型吗?
方法重写:在子类中,出现和父类中一模一样的方法声明的现象。方法重载:同一个类中,出现的方法名相同,参数列表不同的现象。方法重载能改变返回值类型,因为它和返回值类型无关。
final关键字
在Java中声明类、属性和方法时,可使用关键字final来修饰,表示“最终”,final关键字为修饰符
修饰类,类不能被继承
修饰变量,变量就变成了常量,只能被赋值一次
修饰方法,方法不能被重写
final在继承如何体现呢?
由于继承中方法有一个现象:方法重写。所以,父类的功能就会被子类覆盖掉。有时候为了不让子类去覆盖掉父类的功能,只能让他用,所以,针对这种情况,java就提供了一个关键字:final。
示例
多态
可以理解为一个事物的多种表现形式
之前的方法的重载、方法的重写,也是一种多态的表现形式
子类对象的多态性(可以直接应用在抽象类和接口上,会在下面讲)
在Java中,子类的对象可以替代父类的对象使用
我们在之后的学习中会经常与多态打交道,比如:IO、集合、JDBC等等
使用前提
要继承、实现(接口)
要有子类对父类方法的重写,使子类具有不同的方法实现
对象多态性格式
将父类类型的引用指向子类的对象:向上转型(upcasting)
看=左边,是父类的引用
看=右边,是子类的对象
向上转型
子类引用的对象转换为父类类型称为向上转型。通俗地说就是将子类对象转为父类对象。此处父类对象可以是接口
虚拟方法调用
通过父类的引用指向子类的对象实体,当调用方法时,实际执行的是子类重写父类的方法
注意
对象的多态性不适用于子类对象的新方法
子类对象的多态性,并不适用于属性
子类对象的多态性,并不适用于静态方法
向上转型与向下转型
向上转型:子类引用的对象转换为父类类型称为向上转型。通俗地说就是将子类对象转为父类对象。此处父类对象可以是接口
向下转型:父类引用的对象转换为子类类型称为向下转型
多态的好处
可以增强程序的可扩展性及可维护性,使代码更加简洁。
不但能减少编码的工作量,也能大大提高程序的可维护性及可扩展性
单例模式
一个类的对象的实例只有一个
如何设计
如果我们要让类在一个虚拟机中只能产生一个对象,我们首先必须将类的构造方法的访问权限设置为private
不能用new操作符在类的外部直接产生类的对象
调用该类的某个静态方法以返回类内部创建的对象
静态方法只能访问类中的静态成员变量,所以,指向类内部产生的该类对象的变量也必须定义成静态的
分类
饿汉式 线程安全的
懒汉式 非线程安全的
抽象类abstract
抽象类就是一个不具体的类
用abstract关键字来修饰一个类时,这个类叫做抽象类,同理,用abstract关键字来修饰一个方法时,这个方法叫做抽象方法
抽象类和抽象方法必须用abstract关键字修饰
格式
abstract class 类名 {}
public abstract void eat();
抽象类不一定有抽象方法,有抽象方法的类一定是抽象类
抽象类不能实例化
因为它不是具体的。
那么,抽象类如何实例化呢?
按照多态的方式,由具体的子类实例化。其实这也是多态的一种,抽象类多态。
抽象类的子类
如果不想重写抽象方法,该子类是一个抽象类。
重写所有的抽象方法,这个时候子类是一个具体的类。
示例
抽象类——注意:
抽象类有构造器 (凡是类都有构造器)
抽象方法所在的类,一定是抽象类
抽象类中可以没有抽象方法
不能用abstract修饰属性、私有方法、构造器、静态方法、final的方法
抽象类VS一般类:
相同点:
抽象类和一般类都是用来描述事物的,都在内部定了成员。
不同:
一般类有足够的信息描述事物;抽象类描述事物的信息有可能不足。
一般类可以被实例化。抽象类不可以被实例化。
一般类中不能定义抽象方法,只能定非抽象方法。抽象类中可定义抽象方法,同时也可以定义非抽象方法。
抽象方法——注意:
抽象方法必须为public或者protected(因为如果为private,则不能被子类继承,子类便无法实现该方法),缺省情况下默认为public
抽象方法只保留方法的功能,而具体的执行,交给继承抽象类的子类,由子类重写此抽象方法
若子类继承抽象类,并重写了所有的抽象方法,则此类是一个"实体类",即可以实例化
若子类继承抽象类,没有重写所有的抽象方法,意味着此类中仍有抽象方法,则此类必须声明为抽象的!
接口
接口(interface)是抽象方法和常量值的定义的集合
从本质上讲,接口是一种特殊的抽象类,这种抽象类中只包含常量和方法的定义,而没有变量和方法的实现
为什么有接口呢?
Java不支持多重继承
在java中定义类使用关键字class,定义接口使用关键字interface
格式: .
interface InterfaceA{ }
如何实现接口
在java中继承类使用关键字extends,实现接口使用关键字implements
class SubClass implements InterfaceA{ }
类与类之间是继承关系,类与接口之间是实现关系
使用关键字implements实现接口,然后重写接口中定义的抽象方法
接口细节
接口可以看做是一个特殊的抽象类。是常量与抽象方法的一个集合,不能包含变量、一般的方法
接口中的所有成员变量都默认是由public static final修饰的(固定的)。
接口中的所有方法都默认是由public abstract修饰的(固定的)。
由以上两点可知:接口中的成员都是公共的权限
接口是没有构造器的,接口不可以实例化。
接口定义的就是一种功能。此功能可以被类所实现(implements)。
实现接口的类,必须要重写其中的所有的抽象方法,方可实例化。
实现接口的类,若没有重写所有的抽象方法,则此类仍为一个抽象类。
类可以实现多个接口(使用逗号隔开)。java 中的类的继承是单继承的
一个类在继承另一个类的同时,还可以实现多个接口
与继承关系类似,接口与实现类之间存在多态性
接口VS抽象类区别
相同点:
接口和抽象类都不能被实例化。只能被其他类实现和继承。
接口和抽象类都可以包含抽象方法,实现接口和抽象类的类都必须实现这些抽象方法,否则实现的类就是抽象类。
不同点:
抽象类与接口定义不同:抽象类abstract class ,接口 interface
接口里只能包含抽象方法,不包含已经实现的方法;抽象类则完全可以包含普通的方法。
接口里不能定义静态方法;抽象类可以定义静态方法
接口里只能定义静态常量属性,不能定义普通属性;抽象类里既可以定义普通属性,也可以定义静态常量
接口不包含构造函数;抽象类可以包含构造函数,抽象类里的构造函数并不是用于创建对象,而是让其子类调用这些构造函数来完成属于抽象类的初始化操作。
接口不包含初始化块,但抽象类可以包含初始化块
一个类最多只能有一个直接父类,包括抽象类;但一个类可以直接实现多个接口,通过实现多个接口可以弥补Java的单继承不足
注意
接口与接口之间是继成关系,使用extends关键字,而且接口可以多继承 interface InterfaceA extends InterfaceB { }
在开发中,一个类不要去继承一个已经实现好的类,要么继承抽象类,要么实现接口
总结
通过接口可以实现不相关类的相同行为,而不需要考虑这些类之间的层次关系。
通过接口可以指明多个类需要实现的方法,一般用于定义对象的扩张功能。
接口主要用来定义规范。解除耦合关系。
权限修饰符
修饰符:
权限修饰符:private,默认的,protected,public
状态修饰符:static,final
抽象修饰符:abstract
类:
权限修饰符:默认修饰符,public
状态修饰符:final
抽象修饰符:abstract
用的最多的就是:public
成员变量:
权限修饰符:private,默认的,protected,public
状态修饰符:static,final
用的最多的就是:private
构造方法:
权限修饰符:private,默认的,protected,public
用的最多的就是:public
成员方法:
权限修饰符:private,默认的,protected,public
状态修饰符:static,final
抽象修饰符:abstract
用的最多的就是:public
除此以外的组合规则:
成员变量:
public static final
成员方法:
public static
public abstract
public final
包
包(package)是Java提供的一种区别类的名字空间的机制, 是类的组织方式,是一组相关类和接口的集合, 它提供了访问权限和命名的管理机制。
包的应用
1.声明包
在源文件的开始加上:package 包名(要求全部小写,反域名制)
在IDE下声明包的两种方式
通过创建package就表示声明包,然后在包下创建类
创建类的同时指定package
理解:
包在文件中的表现就是文件夹目录结构,功能相似的类放在同一目录下
对类进行了包装,在不同的包中允许有相同类名存在
2.使用包
如果当前类要用到其他包中的类,需要使用import关键字来导入
例如:import java.util.Scanner;
如果需要用到某个包的多个类可以用"*"代替所有类
例:import java.util.*;
包总结
将功能相近的类放在同一个包中,可以方便查找与使用。
由于在不同包中可以存在同名类,所以使用包在一定程度上可以避免命名冲突。
在Java中,某类访问权限是以包为单位的