Java面向对象——继承
Java面向对象的第二大特性就是继承。一个类如果包含着和其他类一样的行为和属性,那么我们在定义子类时,继承这个父类,以便拥有这个类的行为和属性。由此可以发现继承可以提高代码的复用性,这只是继承好处的其中之一,继承给我们程序开发带来的不只是代码的复用性,他有着太多太多的好处。让我们慢慢地体会吧。
继承就是拥有父类的某些行为和特征。在java的世界里,所有的类都是继承至基类Object,所有的类都有着Object的行为和特性。
一、定义:
一个类继承另外一个类,那么这个类叫做子类,被继承的类叫做父类(也叫做基类或超类)如:
A继承了B,那么A就是B的子类,而B是A的父类(基类或超类),A继承了B,A就有B的行为和属性。
如果一个类承至另外一个类,那么用关键子“extends”声明如下:
class B
{
}
class A extend B
{
}
例子:人类是一个类,他描述着所有人的个体的共同个性,在人类的下面又有,儿童,妇女,老人,年经人,学生,老师等。我们用java语言来描述上述:
图下:
1、人类:
分析:对于现代人类来说,他都有着姓名,年龄,吃等等。
class person
{
String name=null;
int age=0;
public person(String name,ing age)
{
this.name=name;
this.age=age;
}
public void eat(String feed)
{
System.out.println(name+“在吃”+feed);
}
}
2、农民
分析:农民也是人类的一种,同用有着名字,年龄,吃等。
class farmer extends
{
public Farmer(Stirng name,ing age)
{
super(name,age)
}
}
3、学生:
分析:学生也是人类的一种,同用有着名字,年龄,吃等
class Student extends
{
public Farmer(Stirng name,ing age)
{
super(name,age)
}
}
4、工人:
分析:工人也是人类的一种,同用有着名字,年龄,吃等
class Worker extends
{
public Farmer(Stirng name,ing age)
{
super(name,age)
}
}
5常景类:
public class client
{
public static void main(String[] args)
{
Farmer farmer=new Farmer(“刘三”,35)
Student student=new Student(“小明”,15);
Worker worker=new Worker(“张打铁”,30);
farmer.eat(“玉米”)
student.eat(“馒头”);
student.eat(“盒饭”);
}
运行结果为:
刘三在吃玉米
小明在吃馒头
张打铁在吃盒饭。
我们分别在三个子类中继承了Person类,然而在子类并没有定义eat方法,而这三个方法中却有了eat这个方法。说明了eat是从Person中继承而来。这可以说得过去,因为是人的话,总是要吃东西的。吃东西,这是人的共同特性。
总结:把一类事物特有我共性抽取出来,封装成一个类,然后拥有这个类的特性的其他类只要继承这个类即可。提高了代码的复用性和降低代码的复杂性以及简化代码。继承了这个类的子类就成为了这个类的体系。拥有这个类的共性。
二、抽象类
上面我们定义的人类中,我们只定义了人类有吃的行为,并不是说人类只有吃的行为,他还应该有劳动,睡觉等等行为。这些的表现行为都各不相同。但是他们确实有这些行为,只有行为的方式不周罢了。
如代码如下:
class farmer extends//农民类
{
public Farmer(Stirng name,ing age)
{
super(name,age)
}
public void work()
{
System.out.println(“农民的工作是耕作”);
}
public void sleep()
{
System.out.println(“农民在家里卧室睡觉”);
}
}
class Student extends//学生
{
public Student (Stirng name,ing age)
{
super(name,age)
}
public void work()
{
System.out.println(“学生的工作是学习”);
}
public void sleep()
{
System.out.println(“学生在寝室睡觉”);
}
}
class Worker extends//工人
{
public Worker (Stirng name,ing age)
{
super(name,age)
}
public void work()
{
System.out.println(“工人的工作是生产产品”);
}
public void sleep()
{
System.out.println(“工人在宿舍睡觉”);
}
}
看看上面这几个类,都有着工作和睡觉的行为。只是它们的行为不同,这时就用到了抽象类。把一类事物抽象的共同特性抽取出来,定义成抽象类,然后让其子类分别去实现各自的行为。这就是抽象。如下:
class abstract person
{
String name=null;
int age=0;
public person(String name,ing age)
{
this.name=name;
this.age=age;
}
public void eat(String feed)
{
System.out.println(name+“在吃”+feed);
}
public abstract void work();
public abstract void sleep();
}
class farmer extends//农民类
{
public Farmer(Stirng name,ing age)
{
super(name,age)
}
public void work()
{
System.out.println(“农民的工作是耕作”);
}
public void sleep()
{
System.out.println(“农民在家里卧室睡觉”);
}
}
class Student extends//学生
{
public Student (Stirng name,ing age)
{
super(name,age)
}
public void work()
{
System.out.println(“学生的工作是学习”);
}
public void sleep()
{
System.out.println(“学生在寝室睡觉”);
}
}
class Worker extends//工人
{
public Worker (Stirng name,ing age)
{
super(name,age)
}
public void work()
{
System.out.println(“工人的工作是生产产品”);
}
public void sleep()
{
System.out.println(“工人在宿舍睡觉”);
}
}
每个子类分别继承了Person类,并实现了抽象方法,场景如下:
public static void main(String[] args)
{
Person p=new Farmer(“刘三”,35)
p.eat(“玉米”);
p.work();
p.sleep();
p =new Student(“小明”,15);
p.eat(“馒头”);
p.work();
p.sleep();
p =new Worker(“张打铁”,30);
p.eat(“盒饭”);
p.work();
p.sleep();
}
运行结果:
刘三在吃玉米
农民的工作是耕作
农民在家里卧室睡觉
小明在吃馒头
学生的工作是学习
学生在寝室睡觉
张打铁在吃盒饭。
工人的工作是生产产品
工人在宿舍睡觉
总结:1、抽象类就把事物的不定确性的行为抽取出来,抽象成这一类事物的抽象描述,简单说,就是不具体的描述。然后让其子类去实现各自的行为。
2、抽象方法只定义了事物的共有特性,没有对事物的该行为进行任何的具体实现。
3、抽象类,他约束了子类的行为特征。换句话说就是只要一个类继承了抽象类,那么这个子类就有着抽象类的该行为。正因为这一定,抽象类实现了多态,何为多态呢,就是一个对象,多种状态,就叫做多态。如上面的对象p他即是农民,也是学生和工人。
抽象类的特点:
1、 抽象类不能被实例化。因为抽象类含有抽象方法,实例了抽象类没有什么意义。
2、 继承了抽象类的子类必须实现其抽象方法,如果未能实现,子类必须声明为抽象类。
3、 抽象方法不能是私有的。因为私有的方法只能在类的内部可见。无法继承。
4、 抽象方法不能修饰为静态方法,因为静态方法直接用类名调用,而抽象方法未有逻辑实现。
5、 抽象类不能修饰为final。因为final修饰的类是不可以被继承的。
何时使用抽象类:
1、 如果一类事物被抽取出来,但又不确定其逻辑功能的实现时,就定义成抽象类。
2、 抽象类必须使用abstract关键字声明。如果有抽象方法,用abstract关键字声明,且没有方法体。
3、 抽象类可以没有抽象方法。
三、更加抽象——接口
接口在我们现实生活中无处不在,例电脑的PIC插槽,USB等等。那么软接口,又指的是什么呢?
接口定义了一序列的行为,这些行为在不同的子类中有不同的实现,然后把实现了接口的类赋给接口,从而实现了多态。从这可看出,接口是对一序列行为进行规范,从而约束了子类必须按照此规范去实现行为。简而言之,接口就是一组行为规范,它规范了子类的行为准则。
1、 接口的定义
(1)定义接口用interface。
(2)接口只能定义常量和抽象方法。
(3)抽象方法不能有逻辑实现(方法体)。
例如:现代电脑外连设备都是USB接口,不管是什么类型的设备,只要实现了USB接口,就可以使用它。这用java来描述是:
interface IUSB
{
public static final String SHAPE=” Rectangular”;
public static final int WIDTH=20;
public static final int HEIGTH=10;
public void open();
public void close();
}
class Computer//电脑
{
public void USB(IUSB usb)//电脑提供USB接口。
{
usb.open();
usb.close();
}
}
class Mouse implement IUSB//鼠标
{
public Mouse(int width,int height)
{
if(!(WIDTH==width&&HEIGTH==height))
{
System.out.println(“usb型号不对”);
return;
}
}
public void open()
{
System.out.println(“usb已经插入”);
System.out.println(“鼠标在工作中”);
}
public void close()
{
System.out.println(“usb已经拔出”);
}
}
class Key implement IUSB//键盘
{
public Mouse(int width,int height)
{
if(!(WIDTH==width&&HEIGTH==height))
{
System.out.println(“usb型号不对”);
return;
}
}
public void open()
{
System.out.println(“usb已经插入”);
System.out.println(“键盘在工作中”);
}
public void close()
{
System.out.println(“usb已经拔出”);
}
}
class Client
{
public static void main(String[] args)
{
IUSB mouse=new Mouse(20,10);
Computer computer=new Computer();
computer.USB(mouse);
IUSB key=new Key(20,10)
computer.USB(key);
}
}
运行结果:
usb已经插入
鼠标在工作中
usb已经拔出
usb已经插入
键盘在工作中
usb已经拔出
看看,电脑只提供了接口,只要实出了接口规则的设备都能插入进去。
总结:1、接口定义了一组规则,然后面向接口编程,后期再把实现了接口规则的子类传进去,使得编程时,不依赖细节。提高了代码的可扩展性。
2、当需求发生改变时,新建一个类实现接口,在子类里重新定义新功能,然后再把新对象传进去即可,而不必修改原来的逻辑实现。提高了代码的可维户性。
何时使用接口呢?
1、 当一个模块的实现功能经常要变动,以便适应需求时,就可以使用接口。使软件架构和逻辑功能实现分离。从而逻辑的改变不会影向到软件的架构。使软件模块间松藕。
2、 团队协作时,可以使用接口,一个团队开发软件架构,另一个团队开发功能实现。只要接口定义出来,在接口的约束下,可以同步开发模块。最后拼接成软件。
使用接口要主意的事项:
1、接口不能实现化。能只由子类完全实现其接口定义的 方法后,才可以由子类实例化。
2、接口不能定义构造函数。
3、接口的成员默认都是公有的。
4、接口只能定义学量,而不能定义变量。
5、接口的方法都是抽象的,不能有方法体。
6、接口的方法不能使用 static 、final关键字修饰。
7、子类如果不能实现全部的抽象方法,那么子类也是抽象的,需要声明为抽象。
抽象类和接口的区别。
1、 解决问题的不同,抽象类是专注于一类事物的共性只是每个共性的表现形式很抽象。而接口是解决模块间的通信,使模块间的依赖关系降低。简单说,就是抽象类专注于实现内容而接口专注于模块间的通信契约。
2、 抽象类可以有构造孔函数、一般函数以及抽象函;而接口只能定义常量和抽象方法。
3、 抽象类只能单继承,因为java的继承机制导致,而java可以通过接口实现多继承。