文章目录
面向对象(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]
二.为什么需要继承
- For Method Overriding.
- 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