7.1 类的封装
封装是面向对象编程的核心思想,将对象的属性和行为封装起来,其载体就是类。
例 7.1
package 第七章;
public class p7 { //创建类
public static void main(String[] args) {//主函数
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);//调用cookName
System.out.println("**请让厨师给我切一点葱花。***"); //输出**请让厨师给我切一点葱花。***
System.out.println(cookName +"切葱花"); //输出切葱花
}
}
运行与结果
System.out.println("**请让厨师给我切一点葱花。***");
System.out.println(cookName+"搅鸡蛋"); //被乱改之后
System.out.println("**请让厨师为我做一份清蒸鱼。***");
System.out.println(cookName+"你是我的小呀小苹果~");//被乱改之后
例7.2
package 第七章;
public class p7 { //创建类
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 第七章;
public class p7 {
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 {
String name;//厨师的名字
public Cook2() {
this.name = "Tom Cruise";//厨师的名字叫Tom Cruise
}
void cutOnion() {//厨师切葱花
System.out.println(name + "切葱花");
}
private void washVegetavles() {//厨师洗蔬菜
System.out.println(name + "洗蔬菜");
}
void cooking(String dish) {//厨师烹饪顾客点的菜
washVegetavles();
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章中曾简要介绍过继承,其基本思想是基于某个父类的扩展,制定出一个新的子类,子类可以继承承父类原有的属性和方法,也可以增加原来父类所不具备的属性和方法,或者直接重写父空中的某些方法。例如,平行四边形是特殊的四边形,可以说平行四边形类继承了四边形类,这时江边形类将所有四边形具有的属性和方法都保留下来,并基于四边形类展了一些新的平行四边形类特有的属性和方法
7.2.1 extends 关键字
在Java中,让一个类继承另一个类,用extends关键字,语法如下:
child extends parents
这里child这个类作为子类继承了parents 这个类,并继承parents中的属性和方法。
child extends parents
举一个简单的例子:每个人都用过计算机,最常见的计算机就是台式机。后来随着科技的发展,计算机变得越来越小,台式机改良成了可移动的笔记本电脑,笔记本电脑又改良成了更轻薄的平板电脑。我们可以把普通计算机看成一个类,那么笔记本电脑和平板电脑都是这个类衔生出的子类。
例7.5
package 第七章; //类包
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 关