勤能补拙
文章持续更新,可以微信搜索【小奇JAVA面试】第一时间阅读,回复【资料】获取福利,回复【项目】获取项目源码,回复【简历模板】获取简历模板,回复【学习路线图】获取学习路线图。
学习好继承和多态是面向对象开发语言中非常重要的一个环节,如果在程序中使用继承和多态得当,整个程序的架构将变得非常有弹性,同时可以减少代码的冗余性。继承机制的使用可以复用一些定义好的类,减少重复代码的编写。多态机制的使用可以动态调整对象的调用,降低对象之间的依存关系。为了优化继承与多态,一些类除了继承父类外还使用接口的形式。Java中的类可以同时实现多个接口,接口被用来简历类与类之间关联的标准。
继承在面向对象开发思想中是一个非常重要的概念,它使整个程序架构具有一定的弹性,在程序中复用一些已经定义完善的类不仅可以减少软件开发周期,也可以提高软件的可维护性和可扩展性。
例如:
public class Parent {//父类
Parent(){
System.out.println("调用父类的Parent()构造方法");
}
}
class SubParent extends Parent{
SubParent(){
System.out.println("调用子类的SubParent()构造方法");
}
public static void main(String[] args) {
SubParent s = new SubParent();
}
}
在开始学习使用class关键字定义类时,就应用到了继承原理,应为在Java中,所有的类都直接或间接继承了java.lang.Object类。Object类是比较特殊的类,它是所有类的父类,是Java类层中的最高层类。当创建一个类时,总是在继承,除非某个类已经指定要从其他类继承,否则它就是从java.lang.Object类继承而来的,可见Java中的每个类都源于java.lang.Object类,如String、Integer等类都是继承于Object类;除此之外,自定义的类也都继承于Object类。由于所有类都是Object子类,所以在定义类时,省略了extends Object关键字。
在Object类中主要包括clone()、finalize()、equals()、toString()等方法,其中常用的两个方法为equals()和toString()方法。由于所有的类都是Object类的子类,所以任何类都可以重写Object类中的方法。
getClass()方法是Object类定义的方法,它会返回对象执行时的Class实例,然后使用此实例调用getName()方法可以取得类的名称。
语法如下:
getClass().getname();
可以将getClass()方法与toString()方法联合使用。
toString()方法的功能是将一个对象返回为字符串形式,它会返回一个String实例。在实际的应用中通常重写toString()方法,为对象提供一个特定的输出模式。当这个类转换为字符串或与字符串连接时,将自动调用重写的toString()方法。
在自定义的类中使用equals()方法进行比较时,equals()方法默认实现是使用“==”运算符比较两个对象的引用地址,而不是比较对象的内容,所以要想真正做到比较两个对象的内容,需要在自定义类中重写equalse()方法。
对象类型的转换在Java编程中经常遇到,主要包括向上转型与向下转型操作。
因为平行四边形是特殊的四边形,也就是说平行四边形是四边形的一种,那么就可以将平行四边形对象看作是一个四边形对象。例如,鸡是家禽的一种,而家禽是动物中的一类 ,那么也可以将鸡对象看作是一个动物对象。
例如:
class Quadrangle {
public static void draw(Quadrangle q){
//SomeSentence
}
}
class Parallelogram extends Quadrangle{
public static void main(String[] args) {
Parallelogram p = new Parallelogram();
draw(p);
}
}
平行四边形类继承了四边形类,四边形类存在一个draw()方法,它的参数是Quadrangle(四边形类)类型,而在平行四边形类的主方法中调用draw()时给予的参数类型却是Parallelogram(平行四边形类)类型的。这里一直在强调一个问题,就是平行四边形也是一种类型的四边形,所以可以将平行四边形类的对象看作是一个四边形类的对象,这就相当于“Quadrangle obj = new Parallelogram()”,就是把子类对象赋值给父类类型的变量,这种技术被称为“向上转型”。试想一下正方形类对象可以作为draw()方法的参数,梯形类对象同样也可以作为draw()方法的参数,如果在四边形类的draw()方法中根据不同的图形对象设置不同的处理,就可以做到在父类中定义一个方法完成各个子类的功能,这样可以使同一份代码毫无差别地运用到不同类型之上,这就是多态机制的基本思想
通过向上转型可以推理出向下转型是将较抽象类转换为较具体的类。这样的转型通常会出现问题,例如,不能说四边形是平行四边形的一种、所有的鸟都是鸽子,因为这非常不合乎逻辑。可以说子类对象总是父类的一个实例,但父类对象不一定是子类的实例。
例如:
class Quadrangle {
public static void draw(Quadrangle q){
//SomeSentence
}
}
class Parallelogram extends Quadrangle{
public static void main(String[] args) {
draw(new Parallelogram());
//将平行四边形类对象看作是四边形对象,称为向上转型操作
Quadrangle q = new Parallelogram();
//Parallelogram p=q;
//将父类对象赋予子类对象,这种写法是错误的
//将父类对象赋予子类对象,并强制转换为子类型,这种写法是正确的
Parallelogram p = (Parallelogram)q;
}
}
当在程序中执行向下转型操作时,如果父类对象不是子类对象的实例,就会发生ClassCastException异常,所以在执行向下转型之前需要养成一个良好的习惯,就是判断父类对象是否为子类对象的实例。这个判断通常使用instanceof操作符来完成。可以使用instanceof操作符判断是否一个类实现了某个接口,也可以用它来判断一个实例对象是否属于一个类。
instanceof的语法格式如下;
myobject instanceof ExampleClass
例如:
class Quadrangle {
public static void draw(Quadrangle q){
//SomeSentence
}
}
class Square extends Quadrangle{
//SomeSentence
}
class Anything{
//SomeSentence
}
class Parallelogram extends Quadrangle{
public static void main(String[] args) {
Quadrangle q = new Quadrangle();//实例化父类对象
//判断父类对象是否为Parallelogram子类的一个实例
if(q instanceof Parallelogram){
Parallelogram p = (Parallelogram)q;//向下转型操作
}
//判断父类对象是否为Square子类的一个实例
if(q instanceof Square){
Square s = (Square) q;//进行向下转型操作
}
//由于q对象不为Anything类的对象,所以这条语句是错误的
}
}
方法的重载就是在同一个类中允许同时存在一个以上的同名方法,只要这些方法的参数个数或类型不同即可。
利用多态可以使程序具有良好的扩展性,并可以对所有类对象进行通用的处理。
例如:
class Quadrangle {
//实例化保存四边形对象的数组对象
private Quadrangle[] qtest = new Quadrangle[6];
private int nextIndex = 0;
public void draw(Quadrangle q){ //定义draw()方法,参数为四边形对象
if(nextIndex < qtest.length){
qtest[nextIndex] = q;
System.out.println(nextIndex);
nextIndex++;
}
}
public static void main(String[] args) {
//实例化两个四边形对象,用于调用draw()方法
Quadrangle q = new Quadrangle();
q.draw(new Square()); //以正方形对象为参数调用draw()方法
q.draw(new Parallelogramgle()); //以平行四边形对象为参数调用draw()方法
}
}
//定义一个正方形类,继承四边形类
class Square extends Quadrangle{
public Square(){
System.out.println("正方形");
}
}
//定义一个平行四边形类,继承四边形类
class Parallelogramgle extends Quadrangle{
public Parallelogramgle(){
System.out.println("平行四边形");
}
}
在解决实际问题时,一般将父类定义为抽象类,需要使用这个父类进行继承与多态处理。回想继承和多态的原理,继承树中越是在上方的类越抽象,如鸽子类继承鸟类、鸟类继承动物类。在多态机制中,并不需要将父类初始化对象,我们需要的只是子类对象,所以在Java语言中设置抽象类不可以实例化对象,因为图形类不能抽象出任何一种具体图形,但它的子类却可以。
抽象类的语法如下:
public abstract class Test{
abstract void testAbstract();//定义抽象方法
}
接口是抽象类的延伸,可以将它看作是纯粹的抽象类,接口中的所有方法都没有方法体。
接口使用interface关键字进行定义,其语法如下:
public interface drawTest{
void draw();//接口内的方法,省略abstract关键字
}
在接口中定义的任何字段都自动是static和final的。
这里的相关内容还没有整理完毕,文章后面持续更新,建议收藏。
文章中涉及到的命令大家一定要像我一样每个都敲几遍,只有在敲的过程中才能发现自己对命令是否真正的掌握了。
可以微信搜索【小奇JAVA面试】第一时间阅读,回复【资料】获取福利,回复【项目】获取项目源码,回复【简历模板】获取简历模板,回复【学习路线图】获取学习路线图。