Java继承与多态

一、继承

继承是由已有类创建新类的机制。子类继承了父类原有的属性与方法,也可以增加新得属性与方法,也可以重写父类中的某些方法。系统默认Object类为所有类的父类。

  • Java中类没有多继承,接口有多继承。

  • 子类继承父类,可以得到父类的全部属性和方法 (除了父类的构造方法),但不见得可以直接访问(比如,父类私有的属性和方法)。

示例

package able;

public class Person {
	String name;
	double height,weight;
	
	public Person(String name, double height, double weight) {
		super();
		this.name = name;
		this.height = height;
		this.weight = weight;
	}

	void thing(){
		System.out.println("工作...");
	}
	
	public String toString() {
		return "姓名:"+name+"身高:"+height+"体重:"+weight;
	}
	
	public static void main(String[] args) {
		Student a = new Student("xxx",0,0,"1000",1);
		Student b = new Student("xxx",0,0,"1010",2);
		System.out.println(a.equals(b));
		new Student("xxx",0,0,"1000",1).thing();
	}
	
}

class Student extends Person{
	
	public Student(String name, double height, double weight,String id,int grade) {
		super(name, height, weight);
		this.id = id;
		this.grade = grade;
		// TODO Auto-generated constructor stub
	}
	
	String id;
	int grade;
	
	void thing() {
		super.thing();
		System.out.println("学习...");
	}
	
	Person who() {
		return new Person("null",175,60);
	}
	
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((id == null) ? 0 : id.hashCode());
		return result;
	}
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Student other = (Student) obj;
		if (id == null) {
			if (other.id != null)
				return false;
		} else if (!id.equals(other.id))
			return false;
		return true;
	}
}
  • student类中的super(name, height, weight);用于调动父类的构造方法
  • student类中的thing()方法里面的super.thing();用于调动父类的thing()方法

二、方法重写

方法重写满足以下规则

  1. “==”: 方法名、形参列表相同。

  2. “≤”:返回值类型和声明异常类型,子类小于等于父类。

  3. “≥”: 访问权限,子类大于等于父类。

以上示例中出现了方法重写
J2SE 5.0以上版本可修改重写方法的返回值类型(重写的返回值类型必须是父类中同意返回值类型的子类

public class TestSubClass {
	TestSubClass(){
		System.out.println("父类构造方法被调用");
	}
	
	TestSubClass test() {
		int a = 1;
		System.out.println("父类test()方法被调用");
		return new TestSubClass();
	}
	
	public static void main(String[] args) {
		SubClass a = new SubClass();
		a.test();
	}
	
}
class SubClass extends TestSubClass{
	
	SubClass(){
		System.out.println("子类构造方法被调用");
	}
	
	SubClass test() {
		System.out.println("子类test()方法被调用");
		return new SubClass();
	}
}

测试结果为:

父类构造方法被调用
子类构造方法被调用
子类test()方法被调用
父类构造方法被调用
子类构造方法被调用
  • 由此可知编译器在调动子类构造方法前先调用父类无参构造方法(有参构造方法需显式使用super调用

三、Object类

Object类主要方法:clone()、finalize()、equals()toString()。最常用的是后面2个。
Object类中不能被重写的方法(被定义为final类型):getClass()、notify()、notifyAll()、wait()等

public class TestObject {
	public String toString() {
		return "在"+getClass().getName()+"类中改写toString()方法";
	}
	public static void main(String[] args) {
		TestObject test = new TestObject();
		System.out.println(test);
	}
}
//结果:在TestObject类中改写toString()方法

四、封装

封装是面向对象的三大特性(封装、继承、多态)之一,封装简单来讲就是将自己的数据隐藏起来。

举个例子:别人向你借钱,传统的面向过程的做法是别人去你家拿,拿多少有时候你也不知道。面向对象的做法是别人向你发出请求:我要借多少钱,至于你借给他多少,如何借这些都是由你自己内部的机制自己完成。用户不需要知道你的内部结构(实现细节)是怎样的,他只需要拿到钱。

五、多态

public class TestPoly {

	public static void animalCry(Animal a) {
		a.shout();
	}
	
	public static void main(String[] args) {
		Animal a1 = new Dog();    //向上转型
		animalCry(a1);
		a1.shout();
		//这句不能通过编译:a1.action();
		
		Animal a2 = new Cat();
		animalCry(a2);
		a2.shout();
		
		Dog d1 = (Dog) a1;    //向下转型,需强制类型转换
		d1.action();
	}
}

class Animal{
	void shout() {
		System.out.println("叫了一声");
	}
}
class Dog extends Animal{

	void shout() {
		System.out.println("旺旺旺");
	}
	
	void action() {
		System.out.println("看门");
	}
}

class Cat extends Animal{
	void shout() {
		System.out.println("喵喵喵");
	}
}
  • 3个条件:继承方法重写父类引用指向子类对象
  • 父类的引用对象无法调用子类特有的方法 (除非向下转型)
  • 向上转型:从具体的类(子类)到抽象的类(父类),安全。
  • 向下转型:与向上转型相反,需要显式说明才能转换。
  • instanceof可以用于判断某个类是否是一个类的子类

你可能感兴趣的:(Java)