Java继承

目录

一、简介:

二、继承的实现:

1.方法重载要求满足:

2.方法重写要求满足:

3.访问修饰符:

4. 继承后的初始化顺序:

三、super关键字:

四、Object类:

1.简介:

2.Object类的一些方法:

①equals方法:

 ②toString方法:

 五、final关键字:

1.对类:

2.对方法:

3.对变量:

4.对不同数据类型:

5.和static关键字一起使用:

六、注解:


一、简介:

  • 是一种类与类之间的关系。
  • 使用已存在的类的定义作为基础建立新类。
  • 新类的定义可以增加新的数据或新的功能,也可用父类的功能,但不能选择性地继承父类。
  • 特点:①利于代码复用   ②缩短开发周期

 满足“A is a B”的关系就可形成继承关系。

二、继承的实现:


父类:

class Animal{
  //公共的属性和方法
}

 子类(继承父类):通过extends关键字实现继承

class Dog extends Animal{
  //子类特有的属性和方法
}

class Cat extends Animal{

}

注意只能是单一继承,一个子类只能有唯一的父类

例:
Eclipse如何创建继承关系?生成子类时在Browse那行选择父类即可。

Animal类:

package com.animal;

public class Animal {
	private String name;
	private int month;
	private String species;
		
	//父类的构造方法既不允许被子类继承,也不允许被重写。
	public Animal() {
		System.out.println("我是父类的无参构造方法");
	}

	public String getName() {
		return name;
	}
	
	public void setName(String name) {
		this.name = name;
	}
	
	public int getMonth() {
		return month;
	}
	
	public void setMonth(int month) {
		this.month = month;
	}
	
	public String getSpecies() {
		return species;
	}
	
	public void setSpecies(String species) {
		this.species = species;
	}
	
	//吃东西
	public void eat() {
		System.out.println(this.getName()+"在吃东西");
	}
	

}

 Cat类:

package com.animal;

public class Cat extends Animal {
	private double weight;  //体重

	//无参构造
	public Cat() {
		System.out.println("我是子类的无参构造方法");
	}

	public double getWeight() {
		return weight;
	}

	public void setWeight(double weight) {
		this.weight = weight;
	}
	
	//跑方法
	public void run() {
		System.out.println(this.getName()+"是一只"+this.getSpecies()+"品种的猫,它在奔跑");
	}

}

Dog类:

package com.animal;

public class Dog extends Animal {
	private String sex;

	public Dog() {
		
	}

	public String getSex() {
		return sex;
	}

	public void setSex(String sex) {
		this.sex = sex;
	}
	
	//睡觉
	public void sleep() {
		System.out.println(this.getName()+this.getMonth()+"几个月大,在睡觉");
	}
	
	public void eat() {
		System.out.println(this.getName()+"最近没有食欲~");
	}
	
	//方法重写
	public void eat(String name) {
		System.out.println(name+"最近没有食欲~");
	}

}

Test类:

package com.test;

import com.animal.Cat;
import com.animal.Dog;

public class Test {

	public static void main(String[] args) {
		Cat one=new Cat();
		one.setName("荣耀");
		one.setSpecies("银渐层");
		one.eat();
		one.run();
		System.out.println("===========================");
		Dog two =new Dog();
		two.setName("小黑");
		two.setMonth(1);
		two.eat();
		two.sleep();
		System.out.println("===========================");
		two.eat("fanfan");

	}
}

结果:

子类能获取父类非私有的成员,父类不能访问子类的特有成员。

1.方法重载要求满足:

①要在同一个类中。

②方法名相同,参数列表不同(参数顺序、个数、类型) 。

③方法的返回值、访问修饰符任意

④方法的参数名任意(如果仅仅是参数名不同,参数类型,参数顺序没有区别也无法构成重载)。

2.方法重写要求满足:

方法的返回值类型、方法名、参数类型、顺序、个数都要与父类继承的方法相同。

①有继承关系的子类中。

②方法名、参数列表相同(参数类型、个数、类型)与父类相同。注意:方法返回值可以与父类不同,允许是子类类型。

③方法的访问修饰符是允许可以有变化的(条件:访问修饰符的限定范围≥父类方法)。

④与方法参数名无关(不强制要求相同)。

父类的构造方法既不允许被子类继承,也不允许被重写。

3.访问修饰符:

访问修饰符

访问

范围

本类同包子类其他

限制

能力

pulic

   小

    ⬆

   大

protected
默认
private

4. 继承后的初始化顺序:

在执行程序时,先完成类的加载。

类在加载时,会优先加载父类的静态信息,然后是子类的静态信息。 加载父类时,会先去加载父类地成员属性,然后执行构造代码块,最后执行构造方法。Object是所有类的父类。

在构造子类对象时,会依次地先去找父类(先构造父类),如果父类还有父类则会追根究源,再依次进行实例化操作。如图:

注意在进行静态信息加载时,访问修饰符不影响成员加载顺序,与书写位置有关。

三、super关键字:

①在继承关系中,子类的构造过程中(即调用子类的构造方法)要调用父类的构造方法。若子类的构造方法中未显式标注,则系统默认调用父类的无参构造。故无参构造很重要!!!

如果子类构造方法中既未显示标注,且父类中也无无参构造方法,就会编译出错。可见,虽然父类的构造方法不可被继承、不可被重写,但会影响子类对象的实例化。

②可以通过:super(参数1,参数2,..);   去指定调用父类允许被访问的其他构造方法。但注意super()语句必须放在子类构造方法有效代码的第一行。super()调用父类的无参构造方法。

③总结:

  • super关键字代表父类引用

                  -访问父类成员方法:super.print();

                  -访问父类属性:super.name;

                  -访问父类构造方法:super();

④super和this对比:

super和this对比
this(当前类对象的引用)super(父类对象的引用)
访问当前类的成员方法
访问当前类的成员属性
访问当前类的构造方法
访问当父类的成员方法
访问当父类的成员属性
访问当父类的构造方法
不能在静态方法中使用

注意:在构造方法中,super和this不能并存,因为它们都要抢占第一行,只能有一个。


四、Object类:

1.简介:

  • Object类是所有类的父类。
  • 1个类没有使用extends关键字明确标识继承关系,则默认继承Object类(包括数组)。
  • Java中的每个类都可使用Object中定义的方法。

Java SE8 API链接:https://docs.oracle.com/javase/8/docs/api/

Object类存放在java.lang包中

2.Object类的一些方法:

例:

①equals方法:

package com.test;

import com.animal.Cat;

public class Test2 {

	public static void main(String[] args) {
		Cat one = new Cat("谦卑", 2); // 父类的带参构造方法
		Cat two = new Cat("谦卑", 2);
		// Object类的equals方法:比较2个引用是否指向同一对象
		boolean a = one.equals(two);
		System.out.println("one和two的引用比较:" + a);
		System.out.println("one和two的引用比较:" + (one == two));
		System.out.println("==============================");
		String str1 = new String("hello");
		String str2 = new String("hello");
		a = str1.equals(str2);
		System.out.println("str1和str2的引用比较:" + a);  //String类自己重写了Object类的equals方法:只比较字符串内容
		System.out.println("str1和str2的引用比较:" + (str1 == str2));

	}
}


继承Object中的equals方法时,比较的是两个引用是否指向同一个对象。子类可以通过重写equals方法来改变比较的内容,如只想比较对象one和two的值:
修改:

package com.animal;

public class Animal {
	private String name;
	private int month;
	private String species;
		
	//父类的构造方法既不允许被子类继承,也不允许被重写。
	public Animal() {
		System.out.println("我是父类的无参构造方法");
	}

	public Animal(String name, int month) {
		this.name = name;
		this.month = month;
		System.out.println("我是父类的带参构造方法");
	}
	
	public String getName() {
		return name;
	}
	
	public void setName(String name) {
		this.name = name;
	}
	
	public int getMonth() {
		return month;
	}
	
	public void setMonth(int month) {
		this.month = month;
	}
	
	public String getSpecies() {
		return species;
	}
	
	public void setSpecies(String species) {
		this.species = species;
	}
	
	//吃东西
	public void eat() {
		System.out.println(this.getName()+"在吃东西");
	}
	
        //equals方法重写
	public boolean equals(Object obj){
		if(obj==null)
			return false;
		Animal temp=(Animal)obj;   //强制类型转换:Object型转Animal型
		if(this.getName().equals(temp.getName()) && (this.getMonth()==temp.getMonth()))
				return true;
		else
			return false;
	}
}
package com.test;

import com.animal.Animal;

public class Test2 {

	public static void main(String[] args) {
		
		Animal one=new Animal("花花",2);  // 父类的带参构造方法
		Animal two=new Animal("花花",2);
		
		boolean flag=one.equals(two);
		System.out.println("one 和 two的引用比较:"+flag);
		System.out.println("one 和 two的引用比较:"+(one==two));
		System.out.println("======================================");
		String str1=new String("hello");
		String str2=new String("hello");
		flag=str1.equals(str2);
		System.out.println("str1 和 str2的引用比较:"+flag);  //String类自己重写了Object类的equals方法:只比较字符串内容
		System.out.println("str1 和 str2的引用比较:"+(str1==str2));

	}

}

改进:

package com.animal;

public class Animal {
	private String name;
	private int month;
	private String species;
		
	//父类的构造方法既不允许被子类继承,也不允许被重写。
	public Animal() {
		System.out.println("我是父类的无参构造方法");
	}

	public Animal(String name, int month) {
		this.name = name;
		this.month = month;
		System.out.println("我是父类的带参构造方法");
	}
	
	public String getName() {
		return name;
	}
	
	public void setName(String name) {
		this.name = name;
	}
	
	public int getMonth() {
		return month;
	}
	
	public void setMonth(int month) {
		this.month = month;
	}
	
	public String getSpecies() {
		return species;
	}
	
	public void setSpecies(String species) {
		this.species = species;
	}
	
	//吃东西
	public void eat() {
		System.out.println(this.getName()+"在吃东西");
	}
	
	/*
	 * //equals方法重写 public boolean equals(Object obj){ if(obj==null) return false;
	 * Animal temp=(Animal)obj; //强制类型转换:Object型转Animal型
	 * if(this.getName().equals(temp.getName()) &&
	 * (this.getMonth()==temp.getMonth())) return true; else return false; }
	 */
	
	//equals方法重载,避免强制类型转换
	public boolean equals(Animal obj){
		if(obj==null)
			return false;
		if(this.getName().equals(obj.getName()) && (this.getMonth()==obj.getMonth()))
				return true;
		else
			return false;
	}
}

 ②toString方法:

  • 输出对象名时,默认会直接调用类中的toString方法
  • 继承Object类中的toString方法时,输出对象的字符串表示形式:类型信息+@+地址信息
package com.test;

import com.animal.Animal;

public class Test2 {

	public static void main(String[] args) {
		
		Animal one=new Animal("花花",2);  // 父类的带参构造方法
		Animal two=new Animal("花花",2);
		
		/*
		 * boolean flag=one.equals(two); System.out.println("one 和 two的引用比较:"+flag);
		 * System.out.println("one 和 two的引用比较:"+(one==two));
		 * System.out.println("======================================"); String str1=new
		 * String("hello"); String str2=new String("hello"); flag=str1.equals(str2);
		 * System.out.println("str1 和 str2的引用比较:"+flag);
		 * //String类自己重写了Object类的equals方法:只比较字符串内容
		 * System.out.println("str1 和 str2的引用比较:"+(str1==str2));
		 */
		
		System.out.println(one.toString());
		System.out.println(one);
	
	}
}

 重写toString方法:

package com.animal;

public class Animal {
	private String name;
	private int month;
	private String species;
		
	//父类的构造方法既不允许被子类继承,也不允许被重写。
	public Animal() {
		System.out.println("我是父类的无参构造方法");
	}

	public Animal(String name, int month) {
		this.name = name;
		this.month = month;
		System.out.println("我是父类的带参构造方法");
	}
	
	public String getName() {
		return name;
	}
	
	public void setName(String name) {
		this.name = name;
	}
	
	public int getMonth() {
		return month;
	}
	
	public void setMonth(int month) {
		this.month = month;
	}
	
	public String getSpecies() {
		return species;
	}
	
	public void setSpecies(String species) {
		this.species = species;
	}
	
	//吃东西
	public void eat() {
		System.out.println(this.getName()+"在吃东西");
	}
	
	/*
	 * //equals方法重写 public boolean equals(Object obj){ if(obj==null) return false;
	 * Animal temp=(Animal)obj; //强制类型转换:Object型转Animal型
	 * if(this.getName().equals(temp.getName()) &&
	 * (this.getMonth()==temp.getMonth())) return true; else return false; }
	 */
	
	/*
	 * //equals方法重载,避免强制类型转换 public boolean equals(Animal obj){ if(obj==null) return
	 * false; if(this.getName().equals(obj.getName()) &&
	 * (this.getMonth()==obj.getMonth())) return true; else return false; }
	 */
	
	//重写toString方法
	public String toString() {
		
		return "昵称:" +this.getName()+";年龄:"+this.getMonth();
	}
	
}
package com.test;

import com.animal.Animal;

public class Test2 {

	public static void main(String[] args) {

		Animal one = new Animal("花花", 2); // 父类的带参构造方法
		Animal two = new Animal("花花", 2);

		/*
		 * boolean flag=one.equals(two); System.out.println("one 和 two的引用比较:"+flag);
		 * System.out.println("one 和 two的引用比较:"+(one==two));
		 * System.out.println("======================================"); String str1=new
		 * String("hello"); String str2=new String("hello"); flag=str1.equals(str2);
		 * System.out.println("str1 和 str2的引用比较:"+flag);
		 * //String类自己重写了Object类的equals方法:只比较字符串内容
		 * System.out.println("str1 和 str2的引用比较:"+(str1==str2));
		 */

		String str1=new String("hello"); 
		System.out.println(one.toString());
		System.out.println(one);
		System.out.println("======================================");
		System.out.println(str1);   //String类重写了toString方法,使输出字符串的值
 
	}

}

 五、final关键字:

1.对类:

  • 在class前面添加final关键字,表示最终的,表示该类不允许有子类、不能被继承、是终极类。
  • final的位置可以与访问修饰符互换,只要写在class关键字前面就行。
public final class Animal{

}

或:

final public class Animal{

}

2.对方法:

在方法的返回值前添加final关键字表示该方法不希望被子类重写,但是可以正常被子类继承使用。

public final void eat() {
		
}

注意final不能修饰构造方法。

3.对变量:

  • 修饰方法内的局部变量:在数据类型前添加final关键字,表示该变量只要在具体使用之前进行赋值即可,一旦赋值不允许被修改。
public void eat(){
  final int a=10;  //方法内的局部变量
}
  • 修饰类中的成员属性:如果在定义时没有进行初始化赋值,则只允许在构造方法构造代码块里对齐赋值。
public class Animal{
  public final int a=15;
}

4.对不同数据类型:

  • 修饰基本数据类型:初始赋值后不能修改
  • 修饰引用数据类型:初始化后不能再指向另一个对象,但指向的对象内容是可变的。
package com.animal;

public class Animal {
	private String name;
	private int month;
	private String species;
		
	//父类的构造方法既不允许被子类继承,也不允许被重写。
	public Animal() {
		System.out.println("我是父类的无参构造方法");
	}

	public Animal(String name, int month) {
		this.name = name;
		this.month = month;
		System.out.println("我是父类的带参构造方法");
	}
	
	public String getName() {
		return name;
	}
	
	public void setName(String name) {
		this.name = name;
	}
	
	public int getMonth() {
		return month;
	}
	
	public void setMonth(int month) {
		this.month = month;
	}
	
	public String getSpecies() {
		return species;
	}
	
	public void setSpecies(String species) {
		this.species = species;
	}
	
	//吃东西
	public void eat() {
		System.out.println(this.getName()+"在吃东西");
	}
	
	public void eat(String name) {
		final int temp;  //方法内的局部变量
		System.out.println(name+"在吃东西");
		temp=12;
		System.out.println(temp);
		
		final Animal animal=new Animal("fanfan",1);
		/* animal=new Animal(); */  //报错,不能修改引用
		animal.month=12;
		animal.name="doudou";  //属性值可修改
	}

}

5.和static关键字一起使用:

  • 表示全局的不允许被修改的内容
  • 修饰程序中的配置信息:表示只需要加载一次又不需要后续修订的内容

6.特点:
使用final关键字可提高性能,但会降低可扩展性、灵活性,需慎重使用。

六、注解:

如何快速重写父类方法?

Alt+/显示提示菜单的信息

  • 是JDK1.5版本引入的一个特性。
  • 可以声明在包、类、属性、方法、局部变量、方法参数......前面,用来对这些元素进行说明、注释。
  • 添加注释相当于打上了某种标记。

 

 @override表示对父类方法重写,可以用来检测重写的方法是否合理。

元注解:用来对注解进行注释。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值