Java第七章总结

7.1、类的继承

继承在面向对象开发思想中是一个非常重要的概念,它可以使整个程序都具有一定的弹性。在程序中复用一些已经定义完善的类,不仅可以减少软件开发周期,也可以维护软件的可维护性和可扩展性。

在Java语言中,一个类继承另一个类需要使用关键字extends,关键字extends的使用方法如下:

class Child extends Parent{}

因为Java只支持单继承,即一个类只能有一个父类,所以类似下面的代码是错误的:

class Child extends Parent1,Parent2{}

子类继承父类之后可以调用父类创建好的属性和方法。

7.2、Object类

在Java中,所有的类都直接或间接继承了java.lang.Object类。Object类是比较特殊的类,它是所有类的父类,是Java类的最高层类。

Object类中主要包括clone()、finalize()、equals()、toString()等方法。其中equals()、toString()较为常用。

所有的类都是Object类的子类,所以任何类都可以重写Object类中的方法。

1、getClass()方法

getClass().getName();

2、toString()方法

 功能:将一个对象返回为字符串形式,它会返回一个String实例。为对象提供一个特定的输出模式。如下图所示:

3、equals()方法 

 equals()方法比较的是两个对象的实际内容。要想真正做到比较,需要在自定义类中重写equals()方法。如下图所示:

7.3、对象类型的转换

1: 向上转型

把子类对象赋值给父类类型的变量,这种技术被称为“向上转型”。

在执行向上转型操作时,父类的对象无法调用子类独有的属性或者方法。

class Quadrangle {                             //四边形类
     public static void draw( Quadrangle q) {  //四边形类中的方法
             //SomeSentence
    }
 }
public class Parallelogram extends Quadrangle {  //平行四边形类,继承了四边形类
     public class void main(String args[]) {     //实例化平行四边形类对象引用
           Parallelogram p = new  Parallelogram();//调用父类方法
            draw(p);
     }
}

2:向下转型

通过向上转型可以推理出向下转型是将较抽象的类转换为较具体的类。

向下转型通常会出现问题:将父类对象直接赋予子类,会发生编译器错误,因为父类对象不一定是子类的实例。

越是具体的对象具有的特性越多,越抽象的对象具有的特性越少。

 class Restaurant  {
	public static void draw( Restaurant q) {
		//SomeSentence
	}
 }
   public class parallelogram extends  Restaurant {
	   public static void main(String[] args[]) {       
			       draw(new parallelogram () );
			       //将平行四边形类对象看作是四边形对象,称为向上转型操作
			       Restaurant q = new  parallelogram();
			       parallelogram p=q; //将父类对象赋予子类对象
	
                 //修改:parallelogram q= (parallelogram) q;		      
 
	}
 
}

7.4、使用instanceof关键字判断对象类型

当程序中执行向下转型操作时,如果父类对象不是子类对象的实例,就会发生异常。所以执行向下转型时要养成一个好习惯,就是判断父类对象是否为子类对象的实例。这个判断通常使instanceof关键字来完成,可以使用instanceof关键字判断是否一个类实现了某个接口,也可以用它来判断一个实例对象是否属于一个类。instanceof的语法格式如下:

myobject instanceof ExampleClass

下图为一个向下转型与instanceof关键字结合的例子:

 7.5、方法的重载

方法重载是指在一个类中定义多个同名的方法,但要求每个方法具有不同的参数的类型或参数的个数。

在本实例中分别定义了 5 个方法,在这 5 个方法中,前两个方法的参数类型不同,并且方法的回值类型也不同,所以这两个方法构成重载关系;前两个方法与第了个方法相比,第 3个方法的参数个数少于前两个方法,所以这 3 个方法也构成了重载关系:最后两个方法相比,发现除了参数的出现顺序不同,其他都相同,同样构成了重载关系。下图表明了所有可以构成了重载的条件。

在谈到参数个数可以确定两个方法是否具有重载关系时,会想到定义不定长参数方法。不定长参数的语法如下:

返回值 方法名(参数数据类型...参数名称)

 

7.6、final关键字

7.6.1.final变量

final 关键字可用于变量声明(定义的变量必须在声明时对其进行赋值操作) ,一旦该变量被设定,就不可以再改变该变量的值。

final double PI=3.14;

 fial 关键字定义的变量必须在声明时对其进行赋值操作。final 除了可以修饰基本数据类型的常量编译器将不会接受。还可以修饰对象引用。由于数组也可以被看作一个对象来引用,所以 final 可以修饰数组。一旦一个对象引用被修饰为 final后,它就只能恒定指向一个对象,无法将其改变以指向另一个对象。一个既是 static来看下面的实例。又是 final 的字段只占据一段不能改变的存储空间。错误实例如下:

7.6.2.final 方法

 final方法不能被覆盖,定义一个为private的方法隐式被指定为final类型,这样无需将一个定义为private的方法再定义为final类型,例如下面:

private final void test() {

...//省略一些程序代码

}

7.6.3.final类

 定义为final的类不能被继承

final的语法如下:

final class 类名{ }

 7.7、多态

利用多态可以使程序具有良好的扩展性,并可以对所有类对象进行通用的处理。在 7.3 节中已经学习过子类对象可以作为父类的对象实例使用,这种将子类对象视为父类对象的做法称为“向上转型”假如现在要编写一个绘制图形的方法 draw0,如果传入正方形对象就绘制正方形,如果传入圆形对象就绘制圆形,这种场景可以使用重载来实现,定义如下:

public void draw(Square s)   //绘制正方形的方法
public void draw(Circular c)  //绘制圆形的方法

但是这种写法有个问题:正方形和圆形都是图形,这场景细分的重载方式不仅增加了代码量,还降低了“易用度”。如果定义一个图形类,让它处理所有继承该类的对象,根据“向上转型”原则可以使每个继承图形类的对象作为 draw0方法的参数,然后在 draw0方法中做一些限定就可以根据不同图形类对象绘制相应的图形。这样处理能够很好地解决代码冗余问题,同时程序也易于维护。代码实例如下:

 

 从本实例的运行结果中可以看出,以不同类对象为参数调用 draw0方法,可以处理不同的图形绘制问题。使用多态节省了开发和维护时间,因为程序员无须在所有的子类中定义执行相同功能的方法避免了大量重复代码的编写。同时,只要实例化一个继承父类的子类对象,即可调用相应的方法,如果需求发生了变更,只需要维护一个 draw()方法即可。

7.8、抽象类与接口

仅用来描述特征且极具抽象性类,在Java中被定义为抽象类。

7.8.1、抽象类

在解决实际问题时,一般将父类定义为抽象类,需要使用这个父类进行继承与多态处理。回想继承与多态原理,继承树中越是在上方的类越抽象,如各自类继承鸟类、鸟类继承动物类等。在多态机制中,并不需要将父类初始化为对象,我们需要的只是子类对象,所以在Java语言中设置抽象类不可以实例化为对象。

使用abstract关键字定义的类称为抽象类,而使用这个关键字定义的方法称为抽象方法。抽象方法没有方法体,这个方法本身没有任何意义,除非它被重写,而承载这个抽象方法的抽象类必须被继承,实际上抽象类除了被继承没有任何意义。定义抽象类的语法如下:

public abstract class Parent{

       abstract void testAbstract();      //定义抽象方法

}

反过来讲,如果声明一个抽象方法,就必须将承载这个抽象方法的类定义为抽象类,不能在非抽象类中获取抽象方法。换句话说,只要类中有一个抽象方法,此类就被标记为抽象类。

抽象类被继承后需要实现其中所有的抽象方法,也就是保证以相同的方法名称、参数列表和返回值类型创建出非抽象方法,当然也可以是抽象方法。

从下图中可以看出,继承抽象类的所有子类需要将抽象类中的抽象方法进行覆盖。

 

这样在多态机制中,就可以将父类修改为抽象类,将 drawO方法设置为抽象方法,然后每个子类都重写这个方法来处理。但这又会出现我们刚探讨多态时讨论的问题,程序中会有太多冗余的代码,同时这样的父类局限性很大,也许某个不需要 draw0方法的子类也不得不重写 draw0方法。如果将draw0方法放置在另外一个类中,让那些需要 draw0方法的类继承该类,不需要 draw0方法的类继承图形类,又会产生新的问题:所有的子类都需要继承图形类,因为这些类是从图形类中导出的,同时某些类还需要 draw0方法,而 Java中规定类不能同时继承多个父类。为了应对这种问题,接口的概念便出现了。

7.8.2、接口


接口是抽象类的延伸,可以将它看作是纯粹的抽象类,接口中的所有方法都没有方法体。对于上节中遗留的问题,可以将drawO方法封装到一个接口中,使需要 draw0方法的类实现这个接口,同时也继承图形类,这就是接口存在的必要性。在图711中,描述了各个子类继承图形类后使用接口的关系。
方法类必须被维抽S
接口使用interface关键字进行定义,其语法如下:

public interface Paintable{

       void draw();        //定义接口方法可省略public abstract关键字

}

java 中不允许出现多重继承,但使用接口就可以实现多重继承。一个类可以同时实现多个接口,因此可以将所有需要继承的接口放置在 implements 关键字后并使用逗号隔开。实现多个接口的语法如下:

class 类名 implements 接口 1,接口2,接口n


但这可能会在一个类中产生庞大的代码量,因为继承一个接口时需要实现接口中所有的方法。个接口可以继承另一个接口,其语法如下:

interface intf1{}

interface intf2 extends intf1{}    //接口继承接口

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值