Java——OOP三大特性之继承(Inheritance)

面向对象(Object Oriented Programming)三大特性

1.封装(Encapsulation):提高代码安全性
2.继承(Inheritance):提高代码复用性
3.多态(Polymorphism):提高代码扩展性

一.继承的定义

Inheritance in Java is a mechanism in which one object acquires all the properties and behaviors of a parent object. It is an important part of OOPs (Object Oriented programming system).
Java中的继承是一种机制,其中一个对象获取父对象的所有属性和行为。它是面向对象编程系统的重要组成部分。[^1]

二.为什么需要继承

  1. For Method Overriding.
  2. For Code Reusability.[^2]

[^2]Reusability: As the name specifies, reusability is a mechanism which facilitates you to reuse the fields and methods of the existing class when you create a new class. You can use the same fields and methods already defined in the previous class.

1.没有用继承前

Class Animal{
	public String name;
	private int age;
	private int id;
	public String getAge(){
				return name;
				}
	 public void setAge(int age){
	 			this.age=age;
	 			}
	 public int getId(){
	 			return id;
	 			}
	 public void setId(int id){
	 			this.id=id;
	 			}
	 public void eat(){
	 			System.out.println(name+"正在吃");
	 			}
	 public void sleep(){
	             System.out.println(name+"正在睡");
}

Class Cat{
public String name;
	private int age;
	private int id;
	public String getAge(){
				return name;
				}
	 public void setAge(int age){
	 			this.age=age;
	 			}
	 public int getId(){
	 			return id;
	 			}
	 public void setId(int id){
	 			this.id=id;
	 			}
	 public void eat(){
	 			System.out.println(name+"正在吃");
	 			}
	 public void sleep(){
	             System.out.println(name+"正在睡");
}
	public void shout(){
					System.out.println(name+"正在叫");
					}
			}

在上述代码中出现了大量的重复代码,使得代码的编写效率大大降低,为了减少代码的重复使用,继承(inheritance)应运而生。

2.应用继承后的变化

继承的具体格式(syntax):

class 子类名 extends 父类名

上述代码进行修改后:

Class Animal{
	public String name;
	private int age;
	private int id;
	public String getAge(){
				return name;
				}
	 public void setAge(int age){
	 			this.age=age;
	 			}
	 public int getId(){
	 			return id;
	 			}
	 public void setId(int id){
	 			this.id=id;
	 			}
	 public void eat(){
	 			System.out.println(name+"is eating");
	 			}
	 public void sleep(){
	             System.out.println(name+"is sleeping");
}

Class Cat extends Animal {
	public void shout(){
					System.out.println(name+"is shouting");
					}
}

public class Test {
    public static void main(String[] args) {
    			Cat cat = new Cat; // 实例化时,只能实例化子类对象Cat,而不能是父类Animal
    			cat.setName("Leo");
    			cat.setAge(2);
    			cat.setId(194122);
				System.out.println(“Name:” + cat.getName + ",Age:" + cat.getAge + ",Id:"+ cat.getId);
				cat.eat();
				cat.sleep();
				cat.shout();
    }
}
}

console:

Name:Leo,Age:2,Id:194122
Leo is eating
Leo is sleeping
Leo is shouting

减少了代码重复率,提高代码整洁度,体现了Code Reuseablity.
Animal与Cat的关系是Cat IS-A Animal

三. 继承的限制

1. 子类继承父类的成员变量

  • 能够继承父类的public和protected成员方法,不能够继承父类的private成员方法。注意:在上述代码中,父类出现了private的成员变量,子类可以通过set来修改,不是继承
  • 对于父类的包访问权限成员变量,如果子类和父类在同一个包下,则子类能够继承,否则不能继承
  • 对于子类可以继承的父类成员变量,如果在子类中出现了同名的成员变量,则会发生隐藏现象,即子类的成员变量会屏蔽父类的同名成员变量。如果要在子类中访问父类的同名成员变量,需要使用super关键字来引用。

super关键字具体实例:

class Animal{
	String color= "white";
}

class Cat extends Animal{
	String color ="black";

	void printColor(){
			System.out.println(color);       //打印子类Cat的成员变量color
			System.out.println(super.color);  //打印父类Animal的成员变量color
			}
	}

class Test1{
		public static void main(String args[]){
			Cat cat =new Cat();
			cat.printColor();
			}
}

Console:

black
white

2.子类继承父类的方法

  • 子类能够继承父类的public和protected成员方法,不能够继承父类的private成员方法
  • 对于父类的包访问权限成员方法,如果子类和父类在同一个包下,则子类能够继承,否则不能继承
  • 对于子类可以继承的父类成员方法,如果在子类中出现了同名的成员方法,则称为覆盖,即子类的成员方法会覆盖父类的同名成员方法。如果要在子类中访问父类中的同名成员方法,需要使用super关键字来进行引用。

super关键字具体实例:

class Animal{
		void eat(){
				System.out.println("I'm eating now!);
				}
		}

class Dog extends Animal{
		void eat(){
				System.out.println("i'm eating apple!");
			}
		void bark(){
				System.out.println("wof..wof...");
			}
		 void together(){
		 		super.eat();   //调用父类的eat()方法
		 		bark();       //调用子类bark()方法
		 		}
		 }
class Test2{
		public static void main(String args[]){
				Dog dog =new dog();
				dog.together();
				}
		}

Console:

i'm eating apple!
wof..wof...

3.构造方法

  • 子类不能继承父类的构造方法
  • 子类可以使用super关键字调用父类构造方法
  • 子类必须调用父类的构造方法
  • super关键字只能放在第一行
  • 如果子类的构造方法中没有显示的调用父类的构造方法,则系统默认调用父类的无参数构造方法。
  • 如果子类构造方法中既没有显示调用父类构造方法,而父类又没有无参数的构造方法,则编译出错

super关键字具体实例:

public class Animal{
	protected String name;
	public Animal(){}    //无参构造
	public Animal(String name){
		this.name=name;
		}
	}
	
public class Cat extends Animal{
	private int id;
	public Cat(){}       //无参构造
	public Cat(String name){
		this.name=name;
		}
	public Cat(String name,int id){
		this.name=name;
		this.id=id;
		}
	}
}

上述代码没有问题,如果把父类的无参构造方法public Animal(){}去掉,则代码会报错。因为子类Cat的构造方法中既没有显示调用父类构造方法,而父类Animal又没有无参数的构造方法,所以编译出错。

如果删掉父类的无参构造方法,则上述代码可以用super关键字改为:

public class Animal{
	protected String name;
	public Animal(String name){
		this.name=name;
		}
	}
	
public class Cat extends Animal{
	private int id;
	public Cat(String name){
		super(“Leo”);
		this.name=name;
		}
	public Cat(String name,int id){
		super(“Leo”);
		this.name=name;
		this.id=id;
		}
	}
}

由于父类没有无参构造方法,所以子类的构造方法必须先使用super方法调用父类的有参构造方法,这样十分麻烦,因此父类在设计构造方法时应该含有一个无参构造方法

四.继承的方式

在这里插入图片描述

1. 单继承Single

上述代码都为单继承

2.多级继承Multilevel

class Animal{  
	void eat(){
		System.out.println("eating...");
		}  
}  

class Dog extends Animal{  
	void bark(){
		System.out.println("barking...");
		}  
}  

class BabyDog extends Dog{  
	void weep(){
		System.out.println("weeping...");
		}  
}  
class TestInheritance2{  
	public static void main(String args[]){  
		BabyDog d=new BabyDog();  
		d.weep();  
		d.bark();  
		d.eat();  
	}
}  

Output:

weeping...
barking...
eating...

3.层级继承Hierarchial

class Animal{  
void eat(){System.out.println("eating...");}  
}  
class Dog extends Animal{  
void bark(){System.out.println("barking...");}  
}  
class Cat extends Animal{  
void meow(){System.out.println("meowing...");}  
}  
class TestInheritance3{  
public static void main(String args[]){  
Cat c=new Cat();  
c.meow();  
c.eat();  
//c.bark();//C.T.Error  
}}

Output:

meowing...
eating...

4.在Java中没有多继承!!!

为什么没有多继承??

class A{  
	void msg(){
		System.out.println("Hello");
		}  
}  
class B{  
	void msg(){
		System.out.println("Welcome");
		}  
}  
class C extends A,B{                 //suppose if it were  
   
 public static void main(String args[]){  
   C obj=new C();  
   obj.msg();                  //Now which msg() method would be invoked?  
	}  
}  

重载(Method Overloading)

在Java中,同一个类中的多个方法可以有相同的名字,只要它们的参数列表不同即可,这被称为方法重载(Method Overloading)。参数列表包括参数的类型,参数的个数,参数的顺序,只要有一个不用就叫参数列表不同。因此,重载是面向对象的一个基本特征

public class Test{
		void test(){
			System.out.println("test1");
			}
		void test(int a){
			System.out.println("test2");
			}
		void test(int a, int b){
			System.out.println(test3);
			}
			void test(double a){
			System.out.println(test4);
			}

但是以下集中情况不是重载
在这里插入图片描述
在这里插入图片描述
更多精彩尽在Blog主页

Reference:
1.https://www.javatpoint.com/inheritance-in-java

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值