类的继承总结

 

一、使用继承的原因和作用:

 

1、  原因:父类拥有的是所有子类所共有的属性和方法,而子类除了继承了父类所有的属性和方法,还有一些特有的属性和方法,这些属性和方法是父类不能拥有的。父类和子类的关系就像一般与特殊的关系。

 

Eg:

 

 

类名

属性

方法

父类

Student

Name,age

Study()

子类

UNStudent

Name,age

Study(),work()

 

         如上例,子类UNStudent(大学生)类除了可以拥有study()方法,还可有work()方法。

 

2、  作用:

 

1)  提高代码的重用性。

 

子类中不需要重新定义父类中的属性和方法,子类的对象也可以引用父类中的属性和方法。

 

2)  提高程序的扩展性。

 

根据继承的原因可知,子类可以拥有自己特有的属性的方法,这样,不同的子类就可以拥有不同的属性和方法,也就提高了程序的扩展性。

 

 

 

二、JAVA继承的语法格式:

 

子类继承的关键字是:extends

 

父类(基类)子类(超类)

 

格式:

 

public class 子类名 extends 父类名{

 

 

 

}

 

 

 

三、子类继承到父类的哪些属性和方法

 

1、  子类可以继承到父类所有的属性和方法,除了构造方法。

 

Eg:

 

//父类Student类
public class Student {
	
		private String name;
		//父类的构造参数
		public Student(String name) {
			this.name = name;
		}
	}
		//子类UNStudent类
public class UNStudent extends Student{
		//子类的构造函数
		public UNStudent(String name) {
			super(name);
		}
}

 

 

如上例,子类并没有继承父类的构造函数,在子类里需要自己定义子类的构造函数。

 

2、访问修饰符(private,protected,默认的,public)决定了子类是否能使用父类中的属性和方法。

 

1)     子类和父类在同一个包下

 

只有父类中private属性和private方法不能被子类或子类的对象调用。

 

父类中protected,默认的,public方法都可以被子类或子类的对象调用。

 

2)     子类和父类不在同一个包下

 

父类中默认的和private属性和方法不能被子类或子类的对象调用。

 

父类中protected属性和方法能被子类调用,但不能被子类的对象调用。

 

父类中public属性和方法都可以被子类或子类的对象调用。

 

Eg:父类和子类在不同包内

package zr.study.test1;

public class Test {

	public static void main(String[] args) {
		
		UNStudent un=new UNStudent();
		//un.name="张三";//name在父类中是私有的,不能被子类的对象调用
		un.work();
		//un.study();//父类和子类在不同的包,子类的对象不能调用父类中默认的方法
	}

}


package zr.study.test2;
//父类Student类
public class Student {
	
	private String name;
	

	protected String getName() {//getName()方法是受保护的,父类和子类在不同的包,getName()只能被子类调用
		return name;
	}

	protected void setName(String name) {//setName()方法是受保护的,父类和子类在不同的包,setName()只能被子类调用
		this.name = name;
	}
	
	void study(){//study()方法为默认的,父类和子类在不同的包,study()不能被子类和子类的对象调用
		name="张三";
		System.out.println("名字为:"+name);//name属性为私有的,只能在该类(父类)中被使用
	}
		
}


package zr.study.test1;

import zr.study.test2.Student;

//子类UNStudent类
public class UNStudent extends Student{
	//子类的构造函数
	public void work(){
		//name="张三";//name在父类中是私有的属性,不能被子类调用
		setName("张三");//可以通过可以访问的方法去给属性赋值				
		System.out.println("名字:"+getName());
		//System.out.println("在子类中调用study()方法,结果为:");
		//study();//父类和子类在不同的包,study()方法在父类中是默认的,不能被子类调用
	}

}

 

 

 

四、     方法重写

 

1、     为什么要方法重写?

 

生活中的例子:

 

老师是一个类,都拥有教书的行为,但是不同专业的老师所教的课程是不一样的。这样就需要方法重写了

 

2、     方法重写的条件:

 

重写后的方法的方法名、返回值、参数类型、参数个数、参数顺序必须和父类的方法一致。

 

 

 

3、     子类方法重写的访问修饰符必须小于或等于父类方法的访问修饰符。

 

如果父类中的方法的访问修饰符为protected的,在子类进行方法重写时,访问修饰符可以是protectedpublic

 

4、     如果实现了方法重写,那么子类的对象优先调用的是子类中的方法。

 

5、     子类可以定义自己的属性和方法。

 

 Eg:

 

//定义了一个老师类Teacher
public class Teacher {
	
	private String name;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
	
	protected void teach(){
		name="张三";
		System.out.println(name+"老师在上课!");
	}

//定义一个子类英语老师类,EnglishTeacher
public class EnglishTeacher extends Teacher{
	
	public void teach(){//重写了父类中的teach()方法
		setName("张三");
		System.out.println(getName()+"在上英语课!");
	}
}

 

 

五、     对象的自动转型

 

1、实现对象的自动转型的条件:存在继承关系。

 

2、格式:

 

父类名对象名 = new 子类构造方法();

 

3、自动转型存在的问题,对象不能引用子类自己定义的方法。

 

Eg:

 

 

public class Test {

	public static void main(String[] args) {
		
		Teacher teacher = new EnglishTeacher();//自动转型
		teacher.teach();
		//teacher.speakTeach();//自动转型后,对象不能调用子类自己定义的方法
	}

}

//定义了一个老师类Teacher
public class Teacher {
	
	private String name;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
	
	protected void teach(){
		name="张三";
		System.out.println(name+"老师在上课!");
	}
	
	
}


//定义一个子类英语老师类,EnglishTeacher
public class EnglishTeacher extends Teacher{
	

	public void teach(){//重写了父类中的teach()方法
		setName("张三");
		System.out.println(getName()+"老师在上英语课!");
	}
	
	//子类中自己定义的一个方法
	public void speakTeach(){
		setName("李四");
		System.out.println(getName()+"老师在上英语口语课!");
	}
}

 

结果:张三老师在上英语课!

 

4、为什么自动转型后,对象不能调用子类定义的方法呢?

 

这个问题是JAVA的编译机制引起的问题。

 

自动转型后,teacher变量时一个Teacher类型的,teacher这个对象只能从Teacher类中去找它要调用的方法,因为speakTeacher()方法是在子类EnglishTeacehr中被定义的,teacherTeacher类中找不到,所以对象不能调用子类定义的方法。

 

如果在子类中重写了父类中的方法,由于方法名和父类中的方法名一样,所以teacher对象可以在父类中找到这个方法名,又自动转型的对象根据是由EnglishTeacher类自动转型的,就可以自动在子类中找到重写的这个方法,所以根据优先原则,teacher对象调用的是子类中重写的方法。

 

5、自动转型的作用:提高代码的重用性。

 

通过自动转型,可以示例化不同子类的对象,自动转型后,这些对象都是父类类型的,这样,就可以把父类类型的一个变量作为参数,把不同子类的对象传给一个方法,从而避免了写多个不同参数类型(不同子类类型)的方法,提高了代码的重用性。

 

Eg:

1

 

 

//定义一个评价老师的方法

 

Public void evaluate(Teacher teacher){

 

   System.out.println(teacher.getName()+”的分数为:”+teacher.getScore());

 

}

 

 

 

如果我们进行了自动转型:

 

Teacher teacher1=new EnglishTeacher();//实例化了一个英语老师类

 

Teacher teacher2=new ComlishTeacher();//实例化了一个计算机老师类

 

 

 

那么我们在调用evaluate()方法的时候可以这样传参:

 

evaluate(teacher1);//传入一个英语老师对象作为参数

 

 

evaluate(teacher2);//传入一个计算机老师对象作为参数

 

 

 

例二:

 

//定义一个评价英语老师的方法

 

Public void evaluate(EnglishTeacher engTeacher){

 

   System.out.println(engTeacher.getName()+”的分数为:”+ engTeacher.getScore());

 

}

 

 

 

 

 

//定义一个评价计算机老师的方法

 

Public void evaluate(ComTeacher comTeacher){

 

   System.out.println(comTeacher.getName()+”的分数为:”+ comTeacher.getScore());

 

}

 

 

 

如果有100种专业类型的老师,那就得写100evaluate()方法(每个方法的参数类型不同)。

 

 

 

比较例一和例二,当然例一更节省代码!

 

 

 

六、     多态

 

多态是JAVA的方法重载、继承、方法重写、自动转型等技术的组合。多态方法调用允许一种类型表现出与其他相似类型之间的区别,只要它们都是从同一父类导出来的。

 

 

 

Eg:

 

**战士和**Boss进行Pk,直到一方的血量为0时结束战斗,输出谁胜利了!

 

要求战士要可以和Boss或者其他的战士对象进行战斗。

 

要求Boss要可以和战士或者其他的Boss对象进行战斗。

 

public class Par {
	private String name;
	private int blood;
	protected Skill [] array;
	private int sum;
	
//	public Par(){
//		
//	}
//	
	public Par(String name, int blood,Skill [] array) {
		//super();
		this.name = name;
		this.blood = blood;
		this.array=array;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getBlood() {
		return blood;
	}

	public void setBlood(int blood) {
		this.blood = blood;
	}
	
	public Skill[] getArray() {
		return array;
	}

	public void setArray(Skill[] array) {
		this.array = array;
	}
	
	public int getSum() {
		return sum;
	}

	public void setSum(int sum) {
		this.sum = sum;
	}

	public void fight(Par p){
		
	}
	

}


public class Soldier extends Par {
	
	public Soldier(String name, int blood, Skill[] array) {
		super(name, blood, array);
		// TODO Auto-generated constructor stub
	}

	public void fight(Par p){
		Random rand=new Random();
		Skill skill=array[rand.nextInt(array.length)];
		p.setBlood(p.getBlood()-skill.getAgressivity());//与Boss类的不同之处	
		p.setSum(p.getSum()+skill.getScore());
		System.out.println(getName()+"攻打"+p.getName()+","+p.getName()+"剩余血量为:"+p.getBlood()+"。"+getName()+"使用技能为:"+skill.getName()+","+getName()+"获得的分数为:"+skill.getScore());
	}
	
	
}


public class Boss extends Par{

	public Boss(String name, int blood, Skill[] array) {
		super(name, blood, array);
		// TODO Auto-generated constructor stub
	}

	public void fight(Par p){
		Random rand=new Random();
		Skill skill=array[rand.nextInt(array.length)];
		p.setBlood(p.getBlood()-2);	//与Soldier类的不同之处
		p.setSum(p.getSum()+skill.getScore());
		System.out.println(getName()+"攻打"+p.getName()+","+p.getName()+"剩余血量为:"+p.getBlood()+"。"+getName()+"使用技能为:"+skill.getName()+","+getName()+"获得的分数为:"+skill.getScore());
		
	}

}


public class Skill {
	private String name;
	private int agressivity;
	private int score;
	
	public Skill(String name, int agressivity, int score) {
		super();
		this.name = name;
		this.agressivity = agressivity;
		this.score = score;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAgressivity() {
		return agressivity;
	}

	public void setAgressivity(int agressivity) {
		this.agressivity = agressivity;
	}

	public int getScore() {
		return score;
	}

	public void setScore(int score) {
		this.score = score;
	}	

}


public class Test {
	
	
	
	public static void main(String[] args) {
		Test t=new Test();
		Skill [] skillArray={new Skill("X战火",5,50),new Skill("X战枪",10,100),new Skill("X战剑",8,80)};
		Random rand=new Random();
		Skill skill=skillArray[rand.nextInt(skillArray.length)];
		Par [] array={new Boss("大魔王",6,skillArray),new Soldier("A战士",8,skillArray),new Boss("小怪兽",8,skillArray),new Soldier("B战士",10,skillArray)};
		Par par1=array[rand.nextInt(array.length)];
		Par par2=array[rand.nextInt(array.length)];
		//System.out.println(!par1.equals(par2));
		int value=rand.nextInt(2);
		t.choose(value,par1,par2);
		
	}

	private void choose(int value,Par par1,Par par2) {
		switch(value){
			case 0:
				if(!par1.equals(par2)){
					while(par1.getBlood()>0&&par2.getBlood()>0){
						par1.fight(par2);
						if(par2.getBlood()<=0){
							System.out.println(par1.getName()+"胜利!"+par1.getName()+"获得的总分数为:"+par1.getSum());
							break;
						}
						par2.fight(par1);
						if(par1.getBlood()<=0){
							System.out.println(par2.getName()+"胜利!"+par2.getName()+"获得的总分数为:"+par2.getSum());
							break;
						}
					}
				}else{
					System.out.println(par1.getName()+"不能和"+par2.getName()+"一起战斗!");
				}
				break;
				
			case 1:
				if(!par1.equals(par2)){
					while(par1.getBlood()>0&&par2.getBlood()>0){
						par2.fight(par1);
						if(par1.getBlood()<=0){
							System.out.println(par2.getName()+"胜利!"+par2.getName()+"获得的总分数为:"+par2.getSum());
							break;
						}
						par1.fight(par2);
						if(par2.getBlood()<=0){
							System.out.println(par1.getName()+"胜利!"+par1.getName()+"获得的总分数为:"+par1.getSum());
							break;
						}
					}
				}else{
					System.out.println(par2.getName()+"不能和"+par1.getName()+"一起战斗!");
				}
				break;
		}
		
	}

}

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值