Java学习之路--继承

Java 继承

继承是java面向对象编程技术的一块基石,因为它允许创建分等级层次的类。继承可以理解为一个对象从另一个对象获取属性的过程。
如果类A是类B的父类,而类B是类C的父类,我们也称C是A的子类,类C是从类A继承而来的。在Java中,类的继承是单一继承,也就是说,一个子类只能拥有一个父类
继承中最常使用的两个关键字是extends和implements。
这两个关键字的使用决定了一个对象和另一个对象是否是IS-A(是一个)关系。
通过使用这两个关键字,我们能实现一个对象获取另一个对象的属性。
所有Java的类均是由java.lang.Object类继承而来的,所以Object是所有类的祖先类,而除了Object外,所有类必须有一个父类。

1、extends

通过过extends关键字可以申明一个类是继承另外一个类而来的,一般形式如下:
// A.java
public class A {
    private int i;
    protected int j;
 
    public void func() {
 
    }
}
 
// B.java
public class B extends A {
}
小结:以上的代码片段说明,B由A继承而来的,B是A的子类。而A是Object的子类,这里可以不显示地声明。
作为子类,B的实例拥有A所有的成员变量,但对于private的成员变量B却没有访问权限,这保障了A的封装性。

IS-A关系

IS-A就是说:一个对象是另一个对象的一个分类。
下面是使用关键字extends实现继承。
public class Animal{
}

public class Mammal extends Animal{
}

public class Reptile extends Animal{
}

public class Dog extends Mammal{
}
基于上面的例子,以下说法是正确的:
--Animal类是Mammal类的父类。
--Animal类是Reptile类的父类。
--Mammal类和Reptile类是Animal类的子类。
--Dog类既是Mammal类的子类又是Animal类的子类。
分析以上示例中的IS-A关系,如下:
--Mammal IS-A Animal
--Reptile IS-A Animal
--Dog IS-A Mammal
因此 : Dog IS-A Animal
通过使用关键字extends,子类可以继承父类所有的方法和属性,但是无法使用 private(私有) 的方法和属性。
我们通过使用instanceof 操作符,能够确定Mammal IS-A Animal

2、Implements

Implements关键字使用在类继承接口的情况下, 这种情况不能使用关键字extends。
实例:
public interface Animal {}

public class Mammal implements Animal{
}

public class Dog extends Mammal{
}

3、instanceof 关键字

可以使用 instanceof 运算符来检验Mammal和dog对象是否是Animal类的一个实例。

<pre name="code" class="java">interface Animal{}

class Mammal implements Animal{}

public class Dog extends Mammal{
   public static void main(String args[]){

      Mammal m = new Mammal();
      Dog d = new Dog();

      System.out.println(m instanceof Animal);
      System.out.println(d instanceof Mammal);
      System.out.println(d instanceof Animal);
   }
} 

 编译结果: 
true
true
true

4、下面介绍一些继承的应用:

一、子类可以继承父类所有public的方法和属性:
class Person {
	private int age;

	public void setAge(int age) {
		if (age < 0 || age > 200)
			age = 0;
		else {
			this.age = age;
		}
	}

	public int getAge() {
		return age;
	}	
}

class Student extends Person{
}

public class Ext {
	public static void main (String args[]) {
		Student stu = new Student();

		stu.setAge(10);

		System.out.println(stu.getAge());
	}
}
编译运行:
10

二、先看一个例子
class Person {
	private int age;

	public void setAge(int age) {
		if (age < 0 || age > 200)
			age = 0;
		else {
			this.age = age;
		}
	}

	public int getAge() {
		return age;
	}	
}

class Student extends Person{
	private String school;

	public void setSchool(String school) {
		this.school = school;
	}

	public String getSchool() {
		return school;
	}	

	public Student(String school) {
		this.school = school;
	}
	
}

public class Ext2 {
	public static void main (String args[]) {
		Student stu = new Student("ustc");

		stu.setAge(10);

		System.out.println(stu.getAge());
		System.out.println(stu.getSchool());
	}
}
运行结果:
10
ustc
分析:
Student stu = new Student("ustc"); //执行Student类的构造函数,this.school = ustc;
stu.setAge(10);//执行Person类的setAge,this.age = age;
System.out.println(stu.getAge());//执行setAge输出10;
System.out.println(stu.getSchool());//执行构造函数,输出ustc

三、看个例子:
class Person {
	private int age;

	public void setAge(int age) {
		if (age < 0 || age > 200)
			age = 0;
		else {
			this.age = age;
		}
	}

	public int getAge() {
		return age;
	}	

	public void printInfo() {
		System.out.println("age = "+age);
	}
}

class Student extends Person{
	private String school;

	public void setSchool(String school) {
		this.school = school;
	}

	public String getSchool() {
		return school;
	}	

	public Student(String school) {
		this.school = school;
	}

	/* override */
	public void printInfo() {
		System.out.println("school = "+school+"; age = "+getAge());
	}
	
}

public class Ext3 {
	public static void main (String args[]) {
		Student stu = new Student("ustc");

		stu.setAge(10);

		System.out.println(stu.getAge());
		System.out.println(stu.getSchool());
		stu.printInfo();
	}
}
运行结果:
10
ustc
school = ustc; age = 10
分析:
看最后一句stu.printInfo()程序输出是school = ustc; age = 10,这就说明Student继承Person并且重写了printInfo方法,最后调用的是重写后的方法。

四、还是先看一个例子
class Person {
	private int age;

	public void setAge(int age) {
		if (age < 0 || age > 200)
			age = 0;
		else {
			this.age = age;
		}
	}

	public int getAge() {
		return age;
	}	

	public void printInfo() {
		System.out.println("age = "+age);
	}

	public Person () {System.out.println("Person ()");}
	public Person (int age) {
		System.out.println("Person (int age)");
		this.age = age;
	}
	
}

class Student extends Person{
	private String school;

	public void setSchool(String school) {
		this.school = school;
	}

	public String getSchool() {
		return school;
	}	

	public Student(String school) {
		/* will call the super() */
		//super();
		super(5);
		System.out.println("Student(String school)");
		this.school = school;
	}

	/* override */
	public void printInfo() {
		System.out.println("school = "+school+"; age = "+getAge());
	}
	
}

public class Ext4 {
	public static void main (String args[]) {
		Student stu = new Student("ustc");

		//stu.setAge(10);

		System.out.println(stu.getAge());
		System.out.println(stu.getSchool());
		stu.printInfo();
	}
}
运行结果:
Person (int age)
Student(String school)
5
ustc
school = ustc; age = 5
分析:
Student stu = new Student("ustc");//首先调用两个类的构造方法,但是调用的顺序是怎么样的呢?super(5)的作用先执行父类的构造方法,即先输出Person (int age),再输出Student(String school);
System.out.println(stu.getAge());//由于上面super(5)传入了5,所以输出5,然后输出ustc;
stu.printInfo();//上同
补充:super关键字的使用
super调用超类的构造器
--使用 super调用构造器的语句必须是子类构造器的第一条语句。
--如果子类的构造器没有显式地(根据传入的参数而定调用哪个构造函数)调用超类的构造器,则将自动调用超类的默认(没有参数)的构造器。

五、例子
abstract class Father {
	private int money;	

	public int getMoney() {return money; }
	public void setMoney(int money) {this.money = money; }

	public abstract void study();
}

interface A {
	public static final int i = 10;
	public abstract int getNum();
}

interface B {
	public static String name = "InterfaceB";
	public abstract String getName();
}

class Son extends Father implements A,B{
	public int getNum() {return i;}
	public String getName() {return name;}
	public void study() {System.out.println("I am study"); }
	
}

public class Ext7 {
	public static void main (String args[]) {
		Son son = new Son();
		System.out.println(son.getName());
		son.study();
	}
}
运行结果:
InterfaceB
I am study
分析:
继承实现了A、B接口,重写了接口的方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值