首页 > 代码库 > 12-13java面向对象之继承

12-13java面向对象之继承

继承

概念:用于扩充已有类的功能。例如:人类作为一个大的类描述了宏观的情况,学生又是一个人类中的特例,学生类既具备人类的共性也有自己的个性。
语法:

Class 子类名称 extends 父类名称{}
注意:子类被成为派生类,父类被成为超类。子类继承了父类的一些可以使用的操作,同时具备了父类不具备的操作。
//本程序是对继承的测试
class Person
{
	//封装属性
	private String name;
	private int age;
	//方法
	public void setName(String n)
	{
		name=n;
	}
	public void setAge(int n)
	{
		if (n>=0)
		{
			age=n;
		}
	}
	public String getName()	
	{
		return name;
	}
	public int getAge()
	{
		return age;
	}
	public String getInfo()
	{
		return "姓名:" + this.name + ",年龄:" + this.age;
	}
}
//子类的继承
class Student extends Person
{
	private String school;
	public void setSchool(String school)
	{
		this.school = school;
	}
	public String getSchool()
	{
		return this.school;
	}
}
public class TestInherance 
{
	public static void main(String[] args) 
	{
		Student stu = new Student();
		stu.setName("Tyrion");				//此方法进行继承
		stu.setAge(24);
		stu.setSchool("BUAA");
		System.out.println( stu.getInfo()+",学校:" + stu.getSchool() );
	}
}
上例中,stu继承了Person类的特性,所有的public方法都可以使用。同时也具备了父类Person不具备的school属性。

子类在继承时只能继承所有非私有操作,父类的所有私有操作是隐式继承,不能直接访问。但是一般都可以通过非私有的方法进行操作。

//本程序是对继承的测试
class Person
{
	private void print()
	{
		System.out.println("hello");
	}
}

//子类的继承
class Student extends Person
{
	
}
public class TestInherance 
{
	public static void main(String[] args) 
	{
		Student stu = new Student();
		stu.print();
	}
}


由于print()方法只在父类中采用定义是private,所以不能访问。

限制:一个子类只能有一个父类,但是允许多层继承。

例如: class A extends B{}  class B extends C{}

现实情况:总是现有父亲才能后有子女,所以说父类优先与子类的产生。子类在进行实例化的时候会默认调用父类的构造方法(默认使用无参),之后调用自己的构造方法,这时候相当于子类的构造方法有 super()

//本程序是对继承的测试
class Person
{
	//父类的构造方法
	public Person()
	{
		System.out.println("!!!!!!这是父类的构造方法");
	}
}

//子类的继承
class Student extends Person
{
	public Student()
	{
        super();
		System.out.println("!!!!!!这是子类的构造方法");
	}
}
public class TestInherance 
{
	public static void main(String[] args) 
	{
		Student stu = new Student();
	}
}
结果;

如果父类中明确定义了无参构造方法的话,super()可以不写,但是如果父类的构造方法使用的是有参数,那么必须写super(参数),且带上相应的参数,写在第一行。——————>相应要求父类的构造方法中,默认写上无参构造。

//本程序是对继承的测试
class Person
{
	//父类的构造方法
	public Person(int i)
	{
		System.out.println("!!!!!!这是父类的构造方法");
	}
}

//子类的继承
class Student extends Person
{
	public Student(int x ,String a)
	{
		super(x);
		System.out.println("!!!!!!这是子类的构造方法");
	}
}
public class TestInherance 
{
	public static void main(String[] args) 
	{
		Student stu = new Student(1,"sd");
	}
}

提示:thissuper都要写在第一行,所以他俩不能同时出现

覆写

继承反生了之后,方法和属性名称相同,该怎么办?

概念:子类和父类的方法名称完全相同。

//本程序是对继承的测试
class Person
{
	public void fun()
	{
		System.out.println("Person类中fun");
	}
}

//子类的继承
class Student extends Person
{
	public void fun()
	{
		System.out.println("Student类中fun");
	}
}
public class TestInherance 
{
	public static void main(String[] args) 
	{
		Student stu = new Student();
		stu.fun();
	}
}
结果:


此时调用使用的是子类的方法,如果子类没有父类的方法,由于继承的关系,子类可以调用父类的非私有操作,那么就调用父类的方法。所以调用的方法是被覆写了的方法。

如果父子类方法名称相同,但是参数列表不同,那么也不是覆写,对象能够自动找到满足要求的方法并调用之。

//本程序是对继承的测试
class Person
{
	public void fun()
	{
		System.out.println("Person类中fun");
	}
}

//子类的继承
class Student extends Person
{
	public void fun(int x)
	{
		System.out.println("Student类中fun");
	}
}
public class TestInherance 
{
	public static void main(String[] args) 
	{
		Student stu = new Student();
		stu.fun();
	}
}

根据“就近取用”的原则,stu对象会在student类中找方法,没有的话,到父类中寻找。

覆写的限制条件:

1.方法的返回值不同,则不能覆写,所以覆写要求返回值类型必须相同。

//本程序是对继承的测试
class Person
{
	public int fun()
	{
		System.out.println("Person类中fun");
		return 1;
	}
}

//子类的继承
class Student extends Person
{
	public String fun()
	{
		System.out.println("Student类中fun");
		return "s";
	}
}
public class TestInherance 
{
	public static void main(String[] args) 
	{
		Student stu = new Student();
		//stu.fun();
		System.out.println(stu.fun());
	}
}
错误信息:TestInherance.java:14: 错误: Student中的fun()无法覆盖Person中的fun()  

 public String fun()                     ^
  返回类型String与int不兼容

限制2:被覆写的方法不能拥有比父类更加严格的权限。

public> default >private

//本程序是对继承的测试
class Person
{
	void fun()
	{
		System.out.println("Person类中fun");
	}
}

//子类的继承
class Student extends Person
{
	private void fun()//必须是比父类更高的权限
	{
		System.out.println("Student类中fun");
	}
}
public class TestInherance 
{
	public static void main(String[] args) 
	{
		Student stu = new Student();
		stu.fun();
	}
}
错误信息:

TestInherance.java:13: 错误: Student中的fun()无法覆盖Person中的fun()
        private void fun()//必须是比父类更高的权限                     ^
  正在尝试分配更低的访问权限; 以前为package
TestInherance.java:23: 错误: fun()可以在Student中访问private
                stu.fun();

但是有时候,子类覆写的父类的方法,但是又想调用父类的方法,怎么办?使用super关键字指明使用父类,否则默认使用this,就近取用,先在子类中寻找后再父类中寻找。

错误版本

//本程序是对继承的测试
class Person
{
	void fun()
	{
		System.out.println("Person类中fun");
	}
}

//子类的继承
class Student extends Person
{
	void fun()
	{
		<span style="background-color: rgb(255, 255, 51);">fun();</span>
		System.out.println("Student类中fun");
	}
}
public class TestInherance 
{
	public static void main(String[] args) 
	{
		Student stu = new Student();
		stu.fun();
	}
}
就近取用,递归死循环

正确版本

//本程序是对继承的测试
class Person
{
	void fun()
	{
		System.out.println("Person类中fun");
	}
}

//子类的继承
class Student extends Person
{
	void fun()
	{
		super.fun();
		System.out.println("Student类中fun");
	}
}
public class TestInherance 
{
	public static void main(String[] args) 
	{
		Student stu = new Student();
		stu.fun();
	}
}
问题来了:如果父类的方法定义为private,那么子类使用default权限是不是覆写呢?
//本程序是对继承的测试
class Person
{
	private void fun()
	{
		System.out.println("Person类中fun");
	}
	public void print()
	{
		this.fun();
	}
}

//子类的继承
class Student extends Person
{
	void fun()
	{
		//super.fun();
		System.out.println("Student类中fun");
	}
}
public class TestInherance 
{
	public static void main(String[] args) 
	{
		Student stu = new Student();
		stu.print();
	}
}
加入覆写成功,那么调用this.fun这个fun肯定就是子类的fun了但是结果


总结:

不管如何操作,只要使用子类的实例化对象,那么通过子类实例化对象调用的方法都是被覆写过的方法

属性的覆写就没有必要再说明了,应为属性都封装起来,没有必要对他们进行直接操作。

总结例题

//本程序是对继承的测试
class Person
{
	private String name;
	private int age;
	public Person()
	{}
	public Person(String name, int age)
	{
		setName(name);
		setAge(age);
	}
	public void setName(String n)
	{
		name=n;
	}
	public void setAge(int n)
	{
		if (n>=0)
		{
			age=n;
		}
	}
	public String getName()	
	{
		return name;
	}
	public int getAge()
	{
		return age;
	}
	public String getInfo()
	{
		return "姓名:" + name +"   " + "年龄:" + age;
	}
}

//子类的继承
class Student extends Person
{
	private String school;
	public Student()
	{}
	public Student(String name, int age ,String school)
	{
		super(name,age);
		setSchool(school);
	}
	public void setSchool(String school)
	{
		this.school = school;
	}
	public String getSchool()
	{
		return this.school;
	}
	//覆写了
	public String getInfo()
	{
		return super.getInfo() + ",学校:" + getSchool();
	}
}
public class TestInherance 
{
	public static void main(String[] args) 
	{
		Student stu = new Student("Tyrion", 24 , "BUAA");
		System.out.println(stu.getInfo());
	}
}

Fianl关键字

用于方法,类,属性

1.使用final定义的类,不能有子类

2.使用final定义的方法,不能被子类覆写

3.使用final定义的变量,变为常量,定义的时候必须有内容,不能够修改。

构造方法私有化(Singleton-单例设计

如果构造方法使用private进行限制,那么在实例化对象的时候就会出错,因为他限制了构造方法只能在内部使用。所以可以编写另一个方法,该方法使用static关键字,不用实例化对象可以返回该类。

//本程序是对继承的测试
class Singleton
{
	//私有化构造方法
	private Singleton()
	{
	}
	public void print()
	{
		System.out.println("hello world");
	}
	public static Singleton getSingleton()
	{
		return new Singleton();
	}
}
public class TestInherance 
{
	public static void main(String[] args) 
	{
		Singleton s = null;
		s.getSingleton().print();
	}
}

但是这种方法太过麻烦,要求:

从类的内部产生一个实例化,用get获取该对象,无论外部有多少对象,只操作了一个对象。

//本程序是对继承的测试
class Singleton
{
	private static final Singleton instance = new Singleton();
	//私有化构造方法
	private Singleton()
	{
	}
	public void print()
	{
		System.out.println("hello world");
	}
	public static Singleton getInstance()
	{
		return instance;
	}
}
public class TestInherance 
{
	public static void main(String[] args) 
	{
		Singleton s = null;
		s.getInstance().print();
	}
}

从类的内部产生了一个实例化对象,get获取该实例化对象,无论外部多少个对象,只操作了这一个对象,所以永远只有一个对象,加上final

多例设计

在单例中准备一个实例化对象,多例设计要求准备多个实例化对象,要想限制实例化个数,必须要有私有化构造方法。同时在类内部准备多个对象,用static返回该对象。

//本程序是对继承的测试
class Color
{
	//属性封装
	private String cl;
	//产生实例化对象
	private static final Color red = new Color("红色");
	private static final Color green = new Color("绿色");
	private static final Color blue = new Color("蓝色");
	//私有化构造方法
	private Color(String cl)
	{
		this.cl = cl;
	}
	//输出实例化对象
	public static Color getColor(int x)
	{
		switch (x )
		{
		case 0:
			return red;
		case 1:
			return green;
		case 2:
			return blue;
		default :
			return null;		
		}
	}
	public String print()
	{
		return this.cl;
	}
}
public class TestInherance 
{
	public static void main(String[] args) 
	{
		Color l = null;
		System.out.println(l.getColor(0).print());
		System.out.println(l.getColor(1).print());
		System.out.println(l.getColor(2).print());
	}
}




祝大家健健康康,快快乐乐。

12-13java面向对象之继承