java学习(十)——继承、final关键字

继承

简单来说就是利用已存在的类构造一个新类,构造的新类复用父类的方法和域。同时,还可以在此基础上,添加自己的域和方法,这个已存在的类叫做父类(超类或基类)、新类称为孩子类(子类或派生类)

 继承层次

由一个公共超类派生出来的所有类的集合被称为继承层次,在继承层次中,从某个特定的类到其祖先的路径被称为该类的继承链,通常一个祖先类可以拥有多个子孙继承链。

特点:

  • java只支持单继承,不支持 多继承。如类A只能有一个父类
  • java支持多重继承,即类B可以继承A,类C又可以继承B

注:在通过扩展超类定义子类时,应该将通用的方法放在超类中,而将具有特殊用途的方法放在子类中。

有以下两个类(来自《java核心技术——卷一》):Empoyee(员工类)、Manager(经理类)。显然,每一名经理是一名员工,经理类和员工类存在着is-a的关系。类似这种关系可以使用继承,这样可以提高代码的复用性。

//员工类
class Employee
{
	//实例域
	private String name;		//姓名
	private double salary;		//薪水
	private int hireDay;		//工龄

	//构造器
	public Employee()
	{
		System.out.println("父类无参构造器");
	}
	public Employee(String name,double salary,int hireDay)
	{
		this.name=name;
		this.salary=salary;
		this.hireDay=hireDay;
		System.out.println("带三个参数的父类构造器");
	}
	//成员方法
	public void setSalary(double salary)
	{
		this.salary=salary;
	}
	public double getSalary()
	{
		return salary;
	}
}
/*
定义子类的格式:
[修饰符] class 子类名 extends 父类名{
	添加的域
	添加的方法
}
*/
class Manager extends Employee
{
    /*
	由于类Manager继承了类Employee,所以Manager类的对象就有四个域,即
		父类的 name、salary、hireDay
		子类的 bonus
	*/
	//添加的域
	private double bonus;	//奖金

	//添加的方法
	public void setBonus(double bonus)
	{
		this.bonus=bonus;
	}
	//构造器
	public Manager()
	{
		System.out.println("这是子类的无参构造方法");
	}
	public Manager(String name,double salary,int hireDay,double bonus)
	{
		System.out.println("子类带四个参数的构造器");
	}
	/*覆盖方法:在父类中的一些方法对子类来说并不一定适合(也称覆盖方法)如
	在Manager继承了父类返回工资的方法getSalary(),但是,Manager类的对象工资还应该加上bonus。这时,就可以重写父类的getSalary()方法。
	*/
	public double getSalary()
	{
		return bonus+super.getSalary();
	}
	
}

方法重写(又称覆盖方法):

如果子类出现了和父类一样的方法声明(方法名、返回类型和参数列表都相同),则称子类重写了父类的方法

 在Manager类中,虽然继承了父类返回工资的方法getSalary(),但是,Manager类的对象工资还应该加上bonus。父类的方法就不适合子类,此时就可以重写父类的getSalary()方法。如下:

    public double getSalary()
    {
        return bonus+salary;
    }

但是上述的方法存在着问题,salary是父类Employee的私有域,只能被自身的方法访问。如何解决这个问题呢?

  1. 把父类的实例域salary定义为非私有的,但是这样就破坏了Employee的封装性。
  2. 调用父类的公有方法来获得salary,下面的代码就是采用这样的方法
public double getSalary()
{
    //super.方法(...)    表示调用父类的方法
	return bonus+super.getSalary();
}

子类构造器和父类构造器

由于子类的构造方法不能访问父类的私有域,所以必须利用父类的构造器对这部分私有域进行初始化。调用父类的构造器格式为

super(....);

如果子类的构造器没有显示的调用父类的构造器,则系统会自动调用父类的无参构造。如果父类没有无参构造器,编译器将会报错。

注意:super语句必须是构造方法的第一条语句。

//构造器
public Manager()
{
    //super();        //隐含
    System.out.println("这是子类的无参构造方法");
}
public Manager(String name,double salary,int hireDay,double bonus)
{
    //super();        //隐含
    System.out.println("子类带四个参数的构造器");
}




public class ManagerTest
{
	public static void main(String[] args)
	{
		Manager m1=new Manager();

		Manager m2=new Manager("叶叶",3000,1000,4);

	}
}

 运行结果

final关键字

修饰变量该变量一旦被赋值就不能被修改

  •  变量是基本数据类型:一旦赋值就不能修改它的值
  • 变量是引用数据类型一旦引用对象就不能改变其引用的对象,但是可以改变其引用对象的实例域。(引用数据类型存储的是对象在堆内存中的地址,一旦被final修饰,它存储的地址就不能改变,但是它所引用的堆内存中饭对象的属性可以改变)

注:可以将实例域定义为final,但是这个final域必须在构造方法执行之后被初始化(实际必须在构造方法之前执行,因此通常在定义final变量时直接初始化),且在初始化后不能再对它进行修改

class Student
{
	String name;
	int age;
	final int lag;	

	{
		lag=2;
	}
	public Student(){
	}
	public Student(String name,int age)
	{
		this.name=name;
		this.age=age;
		//this.lag=2;		//error:可能尚未初始化变量lag
	}
	public String toString()
	{
		return "名字:"+name+",年龄:"+age;
	}
}
class FinalDemo
{
	public static void main(String[] args)
	{
		//final修饰基本数据类型
		final int x;
		x=1;
		System.out.println(x);
		//x=45;		//error:无法为最终变量x分配值
		//System.out.println(x);

		
		System.out.println("----------------");
		//fianl修饰引用数据类型
		final Student s1=new Student("叶叶",18);
		System.out.println(s1.toString());
		s1.name="李**";
		s1.age=12;
		System.out.println(s1.toString());

		//s1=new Studnet("花花",20);	//error:无法为最终变量s1分配值
		

		System.out.println(s1.lag);
	}
}

 运行结果

修饰方法(final方法)表示该方法不能被覆盖(或重写)

修饰类(最终类、final类)阻止继承,表示该类不允许创建子类,一旦一个类用final修饰,该类所有的方法自动的变为final方法,但是该类的实例域并不改为final变量

/*final    //error:无法从最终A进行继承*/ class A
{        
    public final int num=2;
    public final void show()        //error:B中的show()无法覆盖A中的show()
    {
    
    }
}
class B extends A
{
    public void show()
    {
        num=34;
        System.out.println(num);    //error:无法为最终变量num分配值
    }
}
  

 

 

 

返回目录 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章