欢迎来到南方有乔木的博客!!!
博主主页:点击点击!戳一戳!!
博主名:南方有乔木呀
博主简介:
一名在校大学生,正在努力学习Java语言编程。穷且意坚,不坠青云之志,希望能在编程的世界里找到属于自己的光。
跪谢帅气or美丽的朋友们能够帮我点赞! 请对文中内容请多多指教!!!
本节博主对Java中的继承做了总结,大家跟随博主来看看吧!!!
目录
一.什么是继承
概念:继承是面向对象程序设计实现代码复用的重要手段,可以在原有类的基础上进行扩展,增加新功能。
解决的问题:
实现共性抽取,代码复用
示例:
鸡类:跑 吃饭 走路 咕咕咕
猫类:跑 吃饭 走路 喵喵喵
狗类:跑 吃饭 走路 汪汪汪
共性抽取后:
父类动物类:跑 吃饭 走路
子类猫:喵喵喵
子类狗:汪汪汪
子类鸡:咕咕咕
以上例子中狗与猫都具有动物类的所有属性与功能,且都派生出了自己的功能。
共性类称为父类/基类,猫和狗本身是子类/派生类,子类具有父类的所有属性和功能,并且要派生出自己的属性和功能。
二.继承语法格式
class 子类 extends 父类{
//代码
}
子类继承父类需要关键字 extends
代码示例:
/* 以下的三个类都在同一包里,但在不同的.java文件里*/
//Animal 类
package demo;
public class Animal {
String gender;
int age;
public void move(){
System.out.println("移动");
}
public void eat(){
System.out.println("吃饭");
}
}
//Dog类继承Aninmal类
package demo;
public class Dog extends Animal{ //继承动物父类
public String name="旺财";
public void barks(){ //子类增加的新成员
System.out.println("汪汪汪");
}
public static void main(String[] args) {
Dog dog=new Dog();
dog.gender="公";
dog.age=3;
System.out.println(dog.name);
System.out.println(dog.age);
System.out.println(dog.gender);
dog.move();
dog.eat();
dog.barks();
}
}
//Cat类继承Animal类
package demo;
public class Cat extends Animal { //继承动物父类
public String name="大胖";
public void mew(){ //子类增加的新成员
System.out.println("喵喵喵!");
}
public static void main(String[] args) {
Cat cat =new Cat();
cat.age=2;
cat.gender="公";
System.out.println(cat.name);
System.out.println(cat.age);
System.out.println(cat.gender);
cat.eat();
cat.move();
cat.mew();
}
}
注意:
- 1.子类具有父类所有的属性/字段/成员变量和行为/功能/成员方法
- 2.子类必须派生出属于自己的特有成员,否则就没有继承意义。
三.继承成员访问
1.访问父类成员属性
子类中访问父类成员变量,需要注意区分子类与父类是否有同名的成员变量,如果没有同名变量,可在子类中之间直接访问父类成员,如果有同名变量,且一定要访问父类成员时,需要使用super关键字来达到访问同名的父类成员变量的目的。
代码示例:
package Demo;
/*Base.java文件中*/
//Base父类
public class Base {
int a;
int b;
}
//Derived.java文件中
//当子类与父类不存在同名变量时
package Demo;
public class Derived extends Base{
int a;
int b
int c;
public void method(){
a=10;//访问子类a
b=20;//访问子类b
c=30;//访问子类c
//使用super关键字访问基类同名变量
super.a=40 //访问基类的同名变量a
super.b=50 //访问基类的同名变量b
}
}
2.访问父类成员方法
子类中访问父类成员方法,也需要注意区分子类与父类是否有同名的成员方法,如果没有同名变量,可在子类中之间直接访问父类方法,如果有同名方法,且一定要访问父类成员时,需要使用super关键字来达到访问同名的父类成员方法的目的。
代码示例:
package Demo;
/*Base.java文件中*/
public class Base {
public void methodA(){
System.out.println("我是父类成员方法A");
}
public void methodB(){
System.out.println("我是父类成员方法B");
}
public void methodC(){
System.out.println("我父类是成员方法C");
}
}
package Demo;
/*Derived.java文件中*/
public class Derived extends Base{
public void methodA(){
System.out.println("我是子类成员方法A");
}
public void methodB(){
System.out.println("我是子类成员方法B");
}
public void methodC(){
System.out.println("我子类是成员方法C");
}
public void methodD(){
methodA();//优先访问子类的成员方法
methodB();//优先访问子类的成员方法
methodC();//优先访问子类的成员方法
//使用super关键字访问父类中的成员方法
super.methodA();//访问父类的成员方法
super.methodB();//访问父类的成员方法
super.methodC();//访问父类的成员方法
}
}
注意:
- 当子类和父类有同名的成员变量或者方法时,优先访问子类对象自己的成员变量和方法,找到则访问,找不到在父类中找,父类中也找不否则报错。
- 如果子类中的成员方法和父类中的成员方法形成重载(参数列表不同)时,则根据传入的参数选择合适的对象访问。
四.super关键字
子类成员变量和父类成员变量同名时,子类对象访问成员变量时优先访问子类中的成员变量,那么,如果同名时一定要访问父类的成员变量怎么办?设计者因此提出了super关键字。
super关键字作用:子类和父类成员变量和方法同名时可以用super关键字在子类中访问父类成员变量和方法。
super使用示例:
package demo;
/*Base.java文件中*/
public class Base {
int a;
int b;
public void methodA(){
System.out.println("基类中的成员方法A");
}
public void methodB(){
System.out.println("基类中的成员方法B");
}
}
package demo;
/*Derived.java文件中*/
public class Derived extends Base {
int a;
char b;
public void methodA(int a){ //与基类构成重载
System.out.println("我是Derived里的方法A");
}
public void methodB(){ //与基类构成重写
System.out.println("我是Derived里的成员方法B");
}
public void methodC(){
a=100;//优先访问子类
b=200;//优先访问子类
methodA();//与基类匹配 访问基类
methodA(100);//与子类的方法匹配访问子类
//当基类与子类同名且都能匹配时 都是优先访问子类 为了访问基类 设计提出super关键字 可以之间访问基类
super.a=100;
super.b=200;
super.methodA();
super.methodB();
//
}
}
注意:
1.super关键字只能在非静态成员方法中访问。
2.当使用super引用在子类构造方法引用父类构造方法时,它和this引用不能同时出现在子类构造方法里,因为它们都需要占据代码的第一行,,两个引用只能有一个在第一行,这样就会冲突,编译报错。
五.子类构造方法
子类构造对象时,需要先调用基类构造方法,再调用子类构造方法。
代码示例:
package demo;
/*Base.java文件中*/
public class Base {
public Base() {
System.out.println("基类构造方法");
}
}
package demo;
/*Derived.java文件中*/
public class Derived extends Base{
public Derived() {
System.out.println("子类构造方法");
}
}
package demo;
/*Test.java文件中*/
public class Test {
public static void main(String[] args) {
Derived derived=new Derived();
//输出的结果是:
// 基类构造方法
// 子类构造方法
//即用子类构造对象时编译器会自动基类和子类两个构造方法
//因为子类由基类和子类两部分构成
}
}
注意:
- 子类对象成员由子类成员和父类成员构成,所以构造子类对象时,先调用基类的构造方法,再调用子类构造构造方法。
- 如果父类没有显示的定义无参的的构造方法,在子类构造方法的第一行会隐藏有super()调用,在构造子类对象时,编译器会自动的调用父类的构造方法,且默认得父类构造方法是无参的。
六.继承与组合
继承(is-a):
比如,狗是动物,猫是动物,这些属于is-a的关系。
组合(has-a):
继承除了为了实现共性抽取,代码复用以外,还为了能实现组合。
组合(has-a)概念:组合也能达到代码复用的效果,一个对象中包含有其他自定义类型的成员。比如,汽车是由轮胎,方向盘,发动机之类的组成的。
代码示例:
package demo;
class Tire{
//轮胎类
}
class Engine{
//发动机类
public void turnOn(){
System.out.println("启动");
}
public void turnOf(){
System.out.println("熄火");
}
}
class VehicleSystem{
//车载系统类
}
//车类
public class Car {
Tire tire=new Tire();//轮胎
Engine engine=new Engine();//引擎
VehicleSystem vehicleSystem=new VehicleSystem();//系统
public void turnOn(){
engine.turnOn();
}
public void turnOf(){
engine.turnOf();
}
}
//SUV车
class SUV extends Car{
public int id;
public static void main(String[] args) {
SUV suv=new SUV();
suv.turnOn();
suv.turnOf();
}
}
注意:
继承与组合都可以实现代码复用,但是在实际编程中,我们需要根据实际的场景来选择继承还是组合。但是,一般建议能用组合尽量用组合,因为继承可能会面临耦合性过高的问题。因为只要继承,不管子类需不需要这个成员,都会全部继承到子类中。
七.Java只支持单继承
在Java中只支持单继承,不支持多继承,在java中一个子类只能继承一个父类,不支持一个子类继承多个父类。但一个子类继承后可以作为父类让子类继承,实现多层继承.
Java中的单继承可以是一层的单继承,也可以是多重继承,需要注意的是,在设计多层继承时,不要设计超过三层的继承关系,因为,如果设计超过三层的继承关系,那么就会导致耦合性过高,因此一般不建议。
当然Java中多个子类继承一个父类是可以的,但一个子类不能继承多个父类。
如下图所示,Java中的一个子类是不能够同时继承多个父类的,只能有一个父类: