【Java基础】2020.01.06类之间的关系

1.继承

1、被继承的类叫父类或超类(subclass),继承父类的类叫子类或派生类(derived class);

2、子类继承了父类中定义的所有实例变量和方法,并且增加了独特的元素;

3、在Java中,使用extends体现继承关系,其名紧跟父类的类名;

4、可以实现:泛化父类维护共性,细化子类添加特性;

5、Java只支持单一继承,即只能继承一个父类,但可通过接口实现多继承;

6、缺省的自动继承java.lang.Object类,Object类是所有类的顶级父类;

7、子类拥有父类定义的所有属性和方法。但父类可以通过“封装”的思想隐藏某些数据;

8、构造子类实例时,先调用父类的构造方法,然后调用子类的构造方法,两个构造方法都执行。

9、例子:

父类

package com.hyg.ext;
/**
package com.hyg.ext;
/**
 * 父类,属性公有
 * @author 15332
 *
 */
public class Person {
	public String name;//姓名
	public int age;//年龄
	public String gender;//性别
	
	//父类构造方法
	public Person(){
		System.out.println("这是父类的构造方法!");
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getGender() {
		return gender;
	}
	public void setGender(String gender) {
		this.gender = gender;
	}
	
}


子类:

package com.hyg.ext;
/**
 * 子类,派生类
 * @author 15332
 *
 */
public class Student extends Person {
	private double score;//成绩
	private String grade;//年级
	//子类构造方法
	public Student(){
		System.out.println("这是子类的构造方法!");
	}
	public double getScore() {
		return score;
	}
	public void setScore(double score) {
		this.score = score;
	}
	public String getGrade() {
		return grade;
	}
	public void setGrade(String grade) {
		this.grade = grade;
	}
	
}


测试:

package com.hyg.ext;
/**
 * 测试继承关系
 * @author 15332
 *
 */
public class TestDemo {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Student student = new Student();//创建子类对象
		student.setName("高和超");//子类可以调用父类的方法
		System.out.println(student.getName());
		student.setScore(56.56);//子类属性是私有的,只能通过get、set方法访问
		System.out.println(student.getScore());
		Person person = new Person();//创建父类对象,父类只能访问自己的属性和方法
		person.setName("父类");
		System.out.println(person.getName());
		person.age = 18;//父类的公有属性,可以直接赋值
		System.out.println(person.age);
		
	}
}

2.多态

重写

1、子类对父类的方法进行改造,这称为方法的重写(override),重写是Java多态性的一种体现。

2、多态存在的三个必要条件:

继承、重写、父类引用指向子类对象

3、遵循规则:

① 方法签名(方法名和参数列表)必须完全相同;
② 子类方法的返回值类型可以与父类方法返回值类型相同,或是子类;
③ 子类方法声明的异常可以与父类方法声明的异常相同,或是其子类;
④ 父类中的私有方法不能被重写,否在在子类中只是新定义了一个方法,而与父类中的方法无关。
⑤ 子类方法的可访问性可以和父类方法的可访问性相同,或者是更公开。
⑥ 静态方法不 存在重写的概念。
⑦ 对象可以调用子类重写之后的犯法,对于子类改写的方法,是无法访问的。

4、 解释

① 父类可以引用子类重写的方法。
② 父类不能引用子类改写的方法。

5、例子

Animal类

package com.hyg.override;
/**
 * 父类
 * @author 15332
 *
 */
public class Animal {
	public String name;//名字
	/**
	 * 睡觉
	 */
	public void sleep(){
		System.out.println("睡觉!");
	}
	/**
	 * 吃饭
	 */
	public void eat(){
		System.out.println("吃饭!");
	}
	public void func1(){
		System.out.println("animal中的func1");
	}
	
}

Fish类

package com.hyg.override;
/**
 * 子类:鱼类
 * @author 15332
 *
 */
public class Fish extends Animal {
	public void sleep(){
		System.out.println("鱼要睁着眼睛睡觉!");
	}
	
	@Override
	public void eat() {
		System.out.println("鱼要吃虾米!");
	}
	public void func1(){
		System.out.println("fish中的func1");
	}
}


Horse类

package com.hyg.override;
/**
 * 子类:马类
 * @author 15332
 *
 */
public class Horse extends Animal{
	public void sleep(){
		System.out.println("马要站着睡觉!");
	}
	
	@Override
	public void eat() {
		System.out.println("马吃草!");
	}
}


TestDemo类

package com.hyg.override;

public class TestDemo {
	public static void main(String[] args) {
		Animal animal =  new Animal();
		animal.sleep();
		animal.eat();
		
		Animal horse = new Horse();
		horse.sleep();
		horse.eat();
		
		Animal fish =  new Fish();
		fish.sleep();
		fish.eat();
		fish.func1();
		
	}
}


重写和重载的区别

1. 定义区别:

①重载是指不同的函数使用相同的函数名,但是函数的参数个数或类型不同。调用的时候根据函数的参数来区别不同的函数。
②覆盖(也叫重写)是指在派生类中重新对基类中的虚函数(注意是虚函数)重新实现。即函数名和参数都一样,只是函数的实现体不一样。

2.类的关系区别

重写是子类和父类之间的关系,是垂直关系;重载是同一个类中方法之间的关系,是水平关系。

3.产生方法区别

重写只能由一个方法或只能由一对方法产生关系;重载是多个方法之间的关系。

4.参数列表要求区别

重写要求参数列表相同;重载要求参数列表不同。

5.调用方法区别

重写关系中,调用方法体是根据对象的类型来决定;而重载关系是根据调用时的实参表与形参表来选择方法体的。

向上转型

子类向父类的转换称为向上转型。

向上转型语法:

<父类型><引用变量名> = new <子类型>();
子类转父类规则:

1、 将一个父类的引用指向一个子类的对象,称为向上转型,自动进行类型转换;

2、 此时通过父类引用变量调用的方法是子类覆盖或继承父类的方法,不是父类的方法;

3、此时通过父类引用变量无法调用子类特有的方法。

3.super关键字

调用父类的构造方法

虽然构造方法不能够继承,但通过super关键字,在子类构造方法中可以调用父类的构造方法,以便完成父类的初始化。若在子类没有明显写明调用父类构造方法,则系统会自动调用父类不带参数的构造方法

访问父类的属性和方法

可用“ super.属性名“ 引用父类中被子类隐藏(即子类中有与父类同名的属性)的属性或被子类覆盖的方法。
子类的方法覆盖了父类的方法时,可用 “super.方法名(参数列表)” 的方式访问父类中的方法。
在子类中可以添加与父类中属性名重名的属性,但是这样的设计会产生一些不良的后果,不容易开发人员阅读,因此不建议这样设计。

例子

Person类

package com.hyg.ext;
/**
 * 父类,属性公有
 * @author 15332
 *
 */
public class Person {
	public String name;//姓名
	public int age;//年龄
	public String gender;//性别
	
	//父类无参构造方法
	public Person(){
		System.out.println("这是父类的构造方法!");
	}
	//父类有参构造方法
	public Person(String name, int age, String gender) {
		this.name = name;
		this.age = age;
		this.gender = gender;
	}
	//get、set方法
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getGender() {
		return gender;
	}
	public void setGender(String gender) {
		this.gender = gender;
	}
	public void work(){
		System.out.println("工作");
	}
}

Teacher类

package com.hyg.ext;
/**
 * 子类,派生类
 * @author 15332
 *
 */
public class Teacher extends Person {
	private int salsry;//工资
	private String department;//所属院系
	
	//子类有参构造方法
	public Teacher(String name, int age, String gender,int salsry, String department) {
		super(name, age, gender);//调用父类的构造方法
		super.age = age;//调用父类的属性
		this.salsry = salsry;
		this.department = department;
	}
	
	//子类无参构造方法
	public Teacher() {
		super();//调用父类的构造方法
	}

	//get、set方法
	public int getSalsry() {
		return salsry;
	}
	public void setSalsry(int salsry) {
		this.salsry = salsry;
	}
	public String getDepartment() {
		return department;
	}
	public void setDepartment(String department) {
		this.department = department;
	}
	@Override
	public void work() {
		super.work();//调用父类的方法
	}
}


4.final关键字

表示 “ 不可改变的、最终的”

1、 修饰变量:表示此变量不可修改,定义时必须给予初始值,;

2、 修饰方法:表示此方法不可被子类重写;

3、 修饰类:表示此类不可被继承,类中的所有方法都隐式地指定为final。

4、 对对象使用final后,你只能改变此对象属性,而不能将其指向其它对象

例子:

package com.hyg.finalDemo;
/*
 * 类生声明为final之后,不可以继承
 */
public final  class FinalDemo {
	/*常量,对象名.属性*/
	public final int a = 5; 
	/*静态常量,类名.属性名*/
	public static final double PI = 3.25;
	public int b =1;
	/*
	 *  最终方法,final修饰之后,不可以被重写
	 */
	public final void  work(){
		System.out.println("工作");
	}
	private void test() {
		// TODO Auto-generated method stub
		FinalDemo finaldemo = new FinalDemo();
		System.out.println(finaldemo.a);//对象名.属性
		System.out.println(FinalDemo.PI);//类名.属性名
		/*
		 * 对象声明为final,但对象的属性依旧可以改变,而不能其指向其它对象
		 */
		final FinalDemo fdemo = new FinalDemo();
		fdemo.b = 4;
	}
	/*
	 * 内部类,也可以添加访问修饰符
	 * */
	class InnerClass extends FinalDemo{
		/*报错
		public void work() {
			// TODO Auto-generated method stub
		}*/
	}	
}
/*
 * 同级类,不可以添加访问修饰符
 * 一个Java文件中可以存在多个同级类,只能有一个公有的类
 */
 class Son extends FinalDemo{ 
	/*报错
	 public void work() {
		// TODO Auto-generated method stub
	}*/
}

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