第七章 面向对象核心技术

目录

7.1 类的封装

例7.1

例7.2 

例7.3 

7.2.1  extends 关键字 

例7.5

7.2.2  方法的重写

例7.7

7.2.3  所有类的父类——Object类 

例7.8

7.3  类的多态

7.3.1  方法的重载

例7.10

7.3.2  向上转型

例7.11

 7.3.3  向下转型

例7.12

7.3.4  instanceof  关键字

7.4  抽象类与接口

7.4.1  抽象类与抽象方法

7.4.2  接口的声明及实现

例7.15

7.4.3  多重继承

例7.16

7.4.4  区分抽象类与接口

 7.5  访问控制

7.5.1  访问控制符

7.5.2  JAVA 类包

7.5.3  final关键字

例7.17

例7.18

例7.19

例7.20

7.6  内部类

例7.21

例7.22

例7.23

7.6.2  局部内部类

例7.24

7.6.3  匿名内部类

例7.25

7.6.4  静态内部类

例7.26

7.6.5  内部类的继承

例7.27

7.7  小结


7.1 类的封装

        封装是面向对象编程的核心思想,将对象的属性和行为封装起来,其级体就是类本节将谭福介绍如何将类封装。

        举一个简单的例子:我到一个餐馆去吃饭,点了一盘香辣肉丝,感觉很好吃,我就想知道厨师的名字,希望让厨师再为我多做点事情。

例7.1

package Leiduixiang;   //包名
public class Restaurant1 {   //创建类
	public static void main(String[] args) {   //主方法
		// TODO Auto-generated method stub
String cookName="Tom Cruise";   //厨师的名字叫Tom Cruise
System.out.println("**请让厨师为我做一份香辣肉丝。***");   //让厨师为我做一份香辣肉丝
System.out.println(cookName+"切葱花");    //让厨师切葱花
System.out.println(cookName+"洗蔬菜");    //让厨师洗蔬菜
System.out.println(cookName+"开始烹饪"+"香辣肉丝");   //厨师开始烹饪香辣肉丝
System.out.println("**请问厨师叫什么名字?***");    //厨师叫什么名字?
System.out.println(cookName);      //输出厨师的名字
System.out.println("**请让厨师给我切一点葱花。***");   //让厨师给我切一点葱花
System.out.println(cookName+"切葱花");   //让厨师切葱花
	}
}


        所有的逻辑代码全是在main方法中实现的,代码完全暴露,我可以任意删改。如果能随意修改代码,就无法正常运作。为防止其他人修改厨师行为将厨师单独封装成一个类,将厨师的工作定义成厨师类的行为。 

System.out.println("**请让厨师给我切一点葱花。***");

System.out.println(cookName+"搅鸡蛋");   //被乱改之后

 System.out.println("**请让厨师为我做一份清蒸鱼。***");

System.out.println(cookName+"你是我的小呀小苹果~");//被乱改之后

如何防止其他人修改厨师的行为呢?就是将厨师打包成类。

例7.2 

package Leiduixiang;
public class Restaurant2 {   //创建类
	public static void main(String[] args) {   //主方法
		// TODO Auto-generated method stub
cook1 cook=new cook1();     // 创建厨师类的对象
System.out.println("**请让厨师为我做一份香辣肉丝。***");     //输出信息
cook.cooking("香辣肉丝");    // 厨师烹饪香辣肉丝
System.out.println("**你们的厨师叫什么名字?***");    //输出**你们的厨师叫什么名字?***
System.out.println(cook.name);     // 厨师回答自己的名字
System.out.println("**请让厨师给我切一点葱花。***");    //输出**请让厨师给我切一点葱花。***
cook.cutOnion();     // 厨师去切葱花
}
}
class cook1{    //创建Cook1类
	String name;    // 厨师的名字
	public cook1() {    //普通类
		this.name="Tom Cruise";    // 厨师的名字叫Tom Cruise
	}
	void cutOnion() {       //输出厨师切葱花
		System.out.println(name+"切葱花");   //输出厨师切葱花
	}
	void washvegetables() {    // 厨师洗蔬菜
		System.out.println(name+"洗蔬菜");    //输出厨师洗蔬菜
	}
	void cooking(String dish) {    // 厨师烹饪顾客点的菜
		washvegetables();    //洗蔬菜
		cutOnion();     //切葱花
		System.out.println(name+"开始烹饪"+dish);	 //输出name + "开始烹饪" + dish
		}
}

  

        将厨师单独封装成一个类,将厨师的工作定义成厨师类的行为,当我们想让厨师做菜,只能道过调用对象成员方法的方式实现,而我们却不知道这个方法到底是怎么写的,所以就无法随意修改了。餐馆没有义务告诉我们厨师的任何信息,并且厨师也不会随意受我们差遣,所以说厨师有些属性和行为是不予公开的。

例7.3 

package Leiduixiang;    //类包
public class zy {   //创建类
	public static void main(String[] args) {      //主方法
		cook2 cook=new cook2();        //创建类
		System.out.println("**请让厨师为我做一份香辣肉丝。***");   //输出请让厨师为我做一份香辣肉丝
		cook.cooking("香辣肉丝");   //输出香辣肉丝
		System.out.println("**你们的厨师叫什么名字?***");   //输出你们的厨师叫什么名字?
		System.out.println(cook.name);   //输出厨师的名字
		System.out.println("**请让厨师给我切一点葱花。***");  //输出请让厨师给我切一点葱花
		cook.cutOnion();   // 厨师去切葱花
		}}
class cook2{   //创建类
	private string name;   // 厨师的名字
	public cook2() {     //创建Cook2()
		this.name="Tom Cruise";    // 厨师的名字叫Tom Cruise
	}
	private void cutOnion() {     // 厨师切葱花
		System.out.println(name+"切葱花");   //输出Tom Cruise切葱花
	}
	private void washVegetables() {     // 厨师洗蔬菜
		System.out.println(name+"洗蔬菜");    //Tom Cruise洗蔬菜
	}
	void cooking(String dish) {   // 厨师烹饪顾客点的菜
		washVegetables();    //洗蔬菜
		cutOnion() ;      //切洋葱
		System.out.println(name+"开始烹饪"+dish);    // 输出厨师烹饪顾客点的菜
	}
}


例7.4

package Leiduixiang;    //类包 
public class Restaurant4 {      //创建类
		 private cook2 cook=new cook2();  //创建厨师类的对象
		 private void takeOrder(String dish) {    //下单
cook.cooking(dish);         //通知厨师做菜
System.out.println("你的菜好了,请慢用.");     //输出你的菜好了,请慢用  
		 }
		 public  String saySorry() {       //拒绝顾客请求
			 return"抱歉,餐厅不提供此项服务.";    //输出抱歉,餐厅不提供此项服务
		 }
		 public static void main(String[] args) {   //主方法
			 Restaurant4 water=new Restaurant4();    //创建新数组
			 System.out.println("**请让厨师为我做一份香辣肉丝。***");  //输出请让厨师为我做一份香辣肉丝
			 water.takeOrder("鱼香肉丝");      //服务员给顾客下单
			 System.out.println("**请问厨师叫什么名字?***");   //输出请问厨师叫什么名字
			 System.out.println(water.saySorry());    //服务员给顾客善意的答复
			 System.out.println("**请让厨师给我切一点葱花。***");   //输出请让厨师给我切一点葱花
			 System.out.println(water.saySorry());    //服务员给顾客善意的答复
 
}
}


        从这个例子我们就能看出,作为顾客,我始终是和服务员进行交流,再由服务员与厨师进行交流整个过程中,顾客与厨师是完全没有交集的。作为顾客,我不知道我品尝的美食是由哪位厨师用何种方法烹任出来的,这种编程模式,就是封装。
将对象的属性和行为封装起来的载体就是类,类通常对客户隐藏其实现细节,这就是封装的思想。

7.2  类的继承
继承在面向对象开发思想中是一个非常重要的概念,它使整个程序架的具有一定的单色,在程
序中复用已经定义完善的类不仅可以减少软件开发周期,还可以提高软件的可能也都于程
本节将详细讲解类的继承。
在第6章中曾简要介绍过继承,其基本思想是基于某个父类的扩展,制定出一个新的子类,子类可以继承父类原有的属性和方法,也可以增加原来父类所不具备的属性和方法,或者直接重写又类中的某些方法。例如,平行四边形是特殊的四边形,可以说平行四边形类继束了四边形类,这时平行四边形类将所有四边形具有的属性和方法都保留下来,并基于四边形类扩展了一些新的平行四边形类特有的属性和方法。
        下面演示一下继承性。创建一个新类Test,同时创建另一个新类Test2继承 Test类,其中包括重写的父类成员方法(重写的概念将在下文中详细介绍)以及新增成员方法等。在图7.5中描述了类Test与Test2的结构以及两者之间的关系。

 

7.2.1  extends 关键字 

        在Java中,让一个类继承另一个类,用extends关键字,语法如下:

child extends parents

        这里child这个类作为子类继承了parents 这个类,并继承parents中的属性和方法。
child  extends  parents
        举一个简单的例子:每个人都用过计算机,最常见的计算机就是台式机。后来随着科技的发展,计算机变得越来越小,台式机改良成了可移动的笔记本电脑,笔记本电脑又改良成了更轻薄的平板电脑。我们可以把普通计算机看成一个类,那么笔记本电脑和平板电脑都是这个类衔生出的子类。

例7.5

class Computer {//父类:电脑
  String screen = "液晶显示屏";    //定义初值
  void startup() {          //返回参数
   System.out.println("电脑正在开机,请稍等…");  //输出电脑正在开机,请等待...
  }
 }
 public class Pad extends Computer {       //父类:电脑
  String battery ="5000毫安电池";     //子类独有属性
  public static void main(String[] args) {     //主方法
   Pad pc = new Pad();      //电脑类
   System.out.println("computer的屏幕是: " + pc.screen);    //输出computer的屏幕是
   pc.startup();     //返回参数
   Pad ipad = new Pad();     //平板电脑类
   System.out.println("pad的屏幕是:"+ ipad.screen);    //子类可以直接使用父类属性
   System.out.println("pad的电池是:"+ ipad.battery);    //子类独有的属性
   ipad.startup();   //子类可以直接使用父类方法
 }
}

  

7.2.2  方法的重写

1.重写的实现
        继承并不只是扩展父类的功能,还可以重写父类的成员方法。重写(还可以称为覆盖)就是在子类中将父类的成员方法的名称保留,重新编写成员方法的实现内容,更改成员方法的存储权限,或是修改成员方法的返回值类型(重写父类成员方法的返回值类型是基于J2SE 5.0版本以上编译器提供的新功能)。在继承中还有种特殊的重写方式, 子类与父类的成员方法返回值、 方法名称、参数类型及个教完全相同,唯一不同的是方法实现内容,这种特殊重写方式被称为重构。 

         子类重写父类的方法还可以修改方法的返回值类型,但这只是在J2SE 5.0以上的版本中支持的面功能,但这种重写方式需要遵循一个原则,即重写的返回值类型必须是父类中同一方法返回值关主的子类。

例7.6

class Computer2 {    //创建类
 void showPicture() {      //显示图片
  System.out.println("鼠标单击");   //输出鼠标单击
 }
}
public class Pad2 extends Computer2{   //子类:平板电脑   
 void showPicture() {      //显示图片
  System.out.println("手指点击触摸屏");    //输出手指点击触摸屏  
}
 public static void main(String[] args) {    //主方法
  Computer2 pc = new Computer2();     //电脑类   
  System.out.print("pc打开图片: ");    //输出PC打开图片     
  pc.showPicture();       //调用方法
  Pad2 ipad = new Pad2();         //平板电脑类
  System.out.print("ipad打开图片:");      //输出ipad打开图片    
  ipad.showPicture();      //重写父类方法
  Computer2 computerpad = new Pad2();      //父类声明,子类实现
  System.out.print("computerpad打开图片:");       //输出computerpad打开图片  
  computerpad.showPicture();      //调用父类方法,实现子类重写的逻辑
 }
}

 

        从这个结果我们可以看出,虽然子类调用了父类的方法,但实现的是子类重写后的逻辑, 而不是父类原有的逻辑。如果父类声明的对象是由子类实例化的,那么这个对象所调用的方法也是被子类重写过的。

2.super 关键字
        如果子类重写了父类的方法,就再也无法调用到父类的方法了吗?如果想在子类的方法中实现父类原有的方法怎么办?为了解决这种需求,Java 提供了super 关键字。
super关键字的使用方法与this关键字类似。this 关键字代表本类对象,super 关键宇代表父类对象。使用方法如下:

super.property; //调用父类的属性

super.method(); //调用父类的方法

例7.7

class Computer3{    //创建类
 String sayHello() {    //定义一个方法  
  return "欢迎使用";   //返回一个字符串  
 }
}
public class Pad3 extends Computer3{    //子类:平板电脑
   String sayHello() {     //重写方法
    return super.sayHello() +"平板电脑";    //调用父类方法,在其结果后添加字符串
 }
   public static void main(String[] args) {  //主方法
    Computer3 pc = new Computer3();     //电脑类
    System.out.println(pc.sayHello());   //调用父类的方法并输出
    Pad3 ipad = new Pad3();     //平板电脑类
    System.out.println(ipad.sayHello());    //调用子类的方法并输出
   }
}

7.2.3  所有类的父类——Object类 

        在开始学习使用class关键字定义类时,就应用了继承原理,因为在Java中,所有的类都直接或间接继承了java.lang.Object 类。Object 类是比较特殊的类,它是所有类的父类,是Java类层中的最高层类。当创建一一个类时,总是在继承,除非某个类已经指定要从其他类继承,否则它就是从java.lang.Object类继承而来的,可见Java中的每个类都源于java.lang.Object 类,如String、Integer 等类都是继承于Object类;除此之外自定义的类也都继承于O

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值