将多个类抽取位一个独立的类,让独立的类和多个类产生继承关系;
继承的关键字: extends
格式:
class 子类名 extends 父类名 {
...
}
继承的好处:
1)提供了代码复用性,解决了代码的臃肿;
2)它是多态的前提(多态的前提是必须有继承关系);
继承的特点:
子类继承父类,是 继承了父类所有的东西 (成员变量,成员方法,包括私有),但是子类不能使用私有的东西,只能通 过父类的公共的访问间接的让子类访问它;
举例:
class Person{
private String name ;
public void study() {
System.out.println("学生在学习....");
}
public void teach() {
System.out.println("老师在讲课...");
}
public void work() {
System.out.println("程序员在codeing...");
}
}
//学生类
class Student extends Person{}
class Programmer extends Person{}
class Teacher extends Person{}
//测试类
public class ExtendsDemo {
public static void main(String[] args) {
//调用study方法
Student s = new Student() ;
s.study();
System.out.println("--------------");
Programmer p = new Programmer() ;
p.work() ;
System.out.println("--------------");
Teacher t = new Teacher() ;
t.teach();
}
}
继承的另外一个特点:
在Java中,继承只支持单继承,不支持多继承 (子类名 extends 父类名1,父类名2,...) ;
但是,Java是可以支持多层继承;
注意:
类和类之间的关系:继承关系;
类和接口之间的关系:实现关系;
继承中的注意事项:
1)构造方法不能被继承,但是通过super关键字去访问;
2)私有的可以间接的去访问;
3)什么时候使用extends?
举例:
/**
有一个A类
class A{
public void show1(){}
public void show2(){}
}
有一个B类
class B{
public void show1(){}
public void method(){}
}
按照正常的情况:发现A类和B类中有共同的show1()方法,根据继承的概念,---->让B类继承A类;
class B extends A{
public void method(){}
}
没有问题,但是继承了A类,show1(),show2()也继承过来了,可能show2()并不是我想要的功能;对于这种情况不要使用继承;
继承体现的是一种"is a"的关系:
如果A是B的一种或者B是A的一种,这个可以使用继承!
水果
香蕉
苹果
橘子
人类
学生
老师
军人
不要随意的使用继承,只要有"is a"的关系就使用它;
*/
Java开发设计原则:
低耦合,高内聚;
耦合:类和类之间的关系 ,尽量降低耦合性;
内聚:指的是做一件事情能力 (尽量使用一个类完成的事情不要多个类去完成..);
在继承中,成员变量的名称问题:
当前子类继承父类的时候,子类和父类中的成员变量名称不一致的情况,非常简单,分别输出就可以了;
当子类和父类中的成员变量名称一致的情况:
1) 先到子类的局部位置找,如果找到了,就输出;
2) 没有找到,到子类的成员位置找,有就输出;
3) 在类的成员位置还没有找到,直接父类的成员位置找,有就输出;
4) 如果还没有,就保存了,不存在这个变量;
class Fu{
int num = 50 ;
public void method() {
int num = 100 ;
System.out.println(num);
}
}
class Zi extends Fu{
public int num2 =20 ;
public void show() {
System.out.println(num);
System.out.println(num2);
}
}
//测试类
public class ExtendsDemo {
public static void main(String[] args) {
//创建Zi类对象
Zi z = new Zi() ;
z.show();
}
}
// 输出结果为: 50 20
父类和子类之间的相互访问:
要访问这个子类的局部位置的变量,直接可以访问;
需求:要访问Son类的成员位置的这个变量nun,如何访问;
需求:要访问Father类的成员位置的变量nun,如何访问 ?
Java提供了关键字:
super:代表的父类的空间标识(父类的引用或父类的对象);
this 和 super 关键字的用法:
成员变量:
this:this.成员变量; (访问当前类)
super:super.成员变量;(访问父类)
构造方法:
this( ); //无参构造;
this(" ") ; //访问当前类的有参构造;
super( ): //访问的父类的无参构造;
super(" "): //访问的是父类的有参构造;
成员方法:
this.方法名()
super.方法名()
举例:
class Father extends Object{
int num = 100 ;
public Father() {
super();
}
}
//子类
class Son extends Father{
public int num = 50 ;
public void show() {
int num = 20 ;
System.out.println(num);
System.out.println(this.num); //this代表了当前的类对象 :Son
System.out.println(super.num); //super 代表的父类引用
}
}
//测试类
public class ExtendsDemo2 {
public static void main(String[] args) {
//创建对象
Son s = new Son() ;
s.show();
}
}
关于继承的成员的问题:
构造方法:
子类继承父类,都会默认的访问父类的无参构造方法;
假设数据还没有被初始化完毕,所以应该先让父类进行初始化,然后在让子类初始化--->分层初始化;
问题:
如果父类的无参构造没有提供?怎么办?
肯定报错;
如何解决:
1)可以将父类的无参构造提供出来;
2)可以super关键字去访问父类的带参构造;
3)还可以在子类中通过this(),访问本类中的有参构造,间接的去访问父类带参构造子类的构造方法必须有一个(有参构造/无参构造),让父类进行初始化;
继承中的就近原则:
子类继承父类,访问成员方法名不一致的情况,分别调用;
当子类中的成员方名和父类中的成员方法名一致的情况:
1)现在子类的成员位置找,如果有就调用;
2)如果没有找到,在父类的成员位置找,有就调用;
举例:
class Person{
public void method() {
System.out.println("mehtod Person..");
}
public void show() {
System.out.println("show Person");
}
}
//学生类
class Student extends Person{
public void function() {
System.out.println("function student...");
}
public void show() {
System.out.println("show student...");
}
}
//测试类
public class ExtendsDemo {
public static void main(String[] args) {
//创建学生类对象
Student s = new Student() ;
s.method(); //输出的是父类的方法;
s.function(); //输出的是子类的方法;
s.show(); //父类和子类的show方法名一致,使用就近原则,所以调用的是子类的show方法;
}
}
private修饰的父类:
父类中被private修饰的,是可以继承,但是只能间接的去访问私有的;
父类被private修饰成员属性,子类不不能直接访问的;
举例:
class Person{
private int num = 10 ;
public void show() {
System.out.println("show person");
}
//私有的成员方法
private void function() {
System.out.println("function person");
}
public void function2() {
System.out.println(num);
function() ;
}
}
class Student extends Person{
int num2 = 20 ;
public void method(){
System.out.println(num2);
//因为子类中没有变量num,所以就会去父类找,但是父类的变量num是私有的所以子类不能访问,该语句报错;
//System.out.println(num); 报错原因:The field Person.num is not visible :Filed:成员变量 不可用
}
}
public class StudentDemo{
public static void main(String[] args) {
//创建学生对象
Student s = new Student() ;
System.out.println(s.num2) ; //输出子类的变量num2的值 --> 20
s.method();
s.function2();
}
}
举例:
//代码分析:
//进入main方法,给类Z分配单元,今日类Z,因为类Z继承于类X,所以先调用类X,进入类X先执行Y b=new Y()语句,给类Y分配单元,执行类Y的无参构造,输出Y;
//类Y结束,返回类X,继续执行类X的无参构造,输出X;
//类X执行完,返回类Z,执行类Z的语句,首先执行Y y=new Y() 语句,给类Y分配单元,执行类Y的无参构造,输出Y;
//接着执行类Z的无参构造,输出Z;
//输出结果为:YXYZ