首页 > 基础资料 博客日记
Java之继承
2024-05-12 15:00:05基础资料围观171次
一 、继承相关基础
1. 为什么需要继承
先看以下代码
// Dog.javapublic class Dog {string name ;int age ;float weight ;public void eat (){System . out . println ( name + " 正在吃饭 " );}public void sleep (){System . out . println ( name + " 正在睡觉 " );}void Bark (){System . out . println ( name + " 汪汪汪 ~~~" );}}// Cat.Javapublic class Cat {string name ;int age ;float weight ;public void eat (){System . out . println ( name + " 正在吃饭 " );}public void sleep (){System . out . println ( name + " 正在睡觉 " );}void mew (){System . out . println ( name + " 喵喵喵 ~~~" );}}
2.继承概念
3. 继承的语法
修饰符 class 子类 extends 父类 {// ...}
4. 父类成员访问
在继承体系中,子类将父类中的方法和字段继承下来了,那在子类中能否直接访问父类中继承下来的成员呢?
4.1 子类中访问父类的成员变量
public class Base {int a ;int b ;}public class Derived extends Base {int c ;public void method (){a = 10 ; // 访问从父类中继承下来的 ab = 20 ; // 访问从父类中继承下来的 bc = 30 ; // 访问子类自己的 c}}
4.2子类和父类成员变量同名
class Base {int a ;char b ;int c ;}public class Derived extends Base {int a ; // 与父类中成员 a 同名,且类型相同int b ; // 与父类中成员 b 同名,但类型不同public void method (){a = 100 ; // 访问父类继承的 a ,还是子类自己新增的 a ?b='e'; //char类型只有父类中有,故访问父类的bc = 102 ; // 子类没有 c ,访问的肯定是从父类继承下来的 c// d = 103; // 编译失败,因为父类和子类都没有定义成员变量 b}}
4.3 子类中访问父类的成员方法
同变量一样,只是当父类与子类发生方法重写(参数也一样)时访问子类,发生方法重载时根据参数判断访问谁。当父类与子类都没有该方法时,编译器报错。
二、super关键字
1.为什么要使用super关键字
class Base {
int a;
int b;
public void methodB(){
System.out.println("Base中的methodB()");
}
}
public class Derived extends Base{
int a;
int b;
public void methodB() {
super.a = 200;
super.b = 201;
System.out.println("Derived中的methodB()方法");
System.out.println(a);
System.out.println(b); //子类的b
System.out.println(super.a);
System.out.println(super.b); //调用父类的b要用super
super.methodB(); //调用父类的方法要写super
methodB();这里调用自己,形成死递归
}
}
class c {
public static void main(String[] args) {
Derived s=new Derived();
s.a=2;
s.b=5;
s.methodB();
}
}
屏幕输出结果
Derived中的methodB()方法
2
5
200
201
Base中的methodB()
class Base {
int a;
int b;
public void methodB(){
System.out.println("Base中的methodB()");
}
}
public class Derived extends Base{
int a;
int b;
public void methodB() {
public static void main(String[] args) {
super.a = 200;
super.b = 201;
a=2;
b=5;
System.out.println("Derived中的methodB()方法");
System.out.println(a);
System.out.println(b); //子类的b
System.out.println(super.a);
System.out.println(super.b); //调用父类的b要用super
super.methodB(); //调用父类的方法要写super
methodB();这里调用自己,形成死递归
}
}
2.子类构造方法
父子父子,先有父再有子,即:子类对象构造时,需要先调用基类构造方法,然后执行子类的构造方法。
public class Base {public Base (){System . out . println ( "Base()" );}}public class Derived extends Base {public Derived (){// super(); // 注意子类构造方法中默认会调用基类的无参构造方法: super(),// 用户没有写时 , 编译器会自动添加,而且 super() 必须是子类构造方法中第一条语句(类比this在构造方法的作用)System . out . println ( "Derived()" );}}public class Test {public static void main ( String [] args ) {Derived d = new Derived ();}}结果打印:Base ()Derived ()
3.super和this的对比
class Base {int a;public Base(){System.out.println("Base()");}}public class Derived extends Base{int a;public Derived(){System.out.println("Derived()");}this.a=1; //看成Derived.a=1super.a=2; //看成Base.a=2this(); //调用子类构造方法看成Derived()super() //调用父类构造方法看成Base()}//该代码没有主方法,不能运行,只是为了演示方便。
4. 再谈初始化
class Person {public String name ;public int age ;public Person ( String name , int age ) {this . name = name ;this . age = age ;System . out . println ( "Person :构造方法执行 " );}{System . out . println ( "Person :实例代码块执行 " );}static {System . out . println ( "Person :静态代码块执行 " );}}class Student extends Person {public Student ( String name , int age ) {super ( name , age );System . out . println ( "Student :构造方法执行 " );}{System . out . println ( "Student :实例代码块执行 " );}static {System . out . println ( "Student :静态代码块执行 " );}}public class TestDemo4 {public static void main ( String [] args ) {Student student1 = new Student ( " 张三 " , 19 );System . out . println ( "===========================" );Student student2 = new Student ( "gaobo" , 20 );}public static void main1 ( String [] args ) {Person person1 = new Person ( "bit" , 10 );System . out . println ( "============================" );Person person2 = new Person ( "gaobo" , 20 );}//执行结果Person :静态代码块执行Student :静态代码块执行Person :实例代码块执行Person :构造方法执行Student :实例代码块执行Student :构造方法执行===========================Person :实例代码块执行Person :构造方法执行Student :实例代码块执行Student :构造方法执行
首先说下类的加载(在生成class文件创建类时就执行了)会导致静态成员变量先初始化(父类的静态变量先初始化,子类的静态变量后初始化),而后是静态代码块初始化(父类的静态代码块先执行,子类的静态代码块再执行),因为类的加载只有一次,所以它们只能执行一次。然后就按上面的顺序。注意如果没有静态,则先父类先把构造方法执行完后再初始化实例成员变量。
三、protected关键字
public class Date3 {
protected int a=30;
}
class Date2 extends Date3{
public void a(){
System.out.println(super.a);
System.out.println(a);
//以下的部分复杂化了,在继承关系中我们可以直接使用a,这里运行没有问题
Date3 date3 = new Date3();
System.out.println(date3.a);
}
public static void main(String[] args) {
Date2 date2 =new Date2();
Date3 date3 =new Date3();
System.out.println(date2.a);
System.out.println(date3.a);
date2.a();
}
}
我们看下不同包的情况
package cot;
public class Date1 {
protected int a=30;
}
package com;
import cot.Date1;
class Date2 extends Date1 {
public void a(){
System.out.println(super.a);
System.out.println(a);
//以下代码会报错
Date1 date1 = new Date1();
System.out.println(date1.a);
}
public static void main(String[] args) {
Date2 date2 =new Date2();
Date1 date1 =new Date1();
System.out.println(date2.a);
System.out.println(date1.a); //这里会报错:a 在 cot.Date1 中是 protected 访问控制
date2.a();
}
}
package cot;
public class Date1 {
protected int a=30;
}
package com;
import cot.Date1;
class Date2 extends Date1 {
public void a(){
System.out.println(super.a);
}
public static void main(String[] args) {
Date2 date2 =new Date2();
// Date1 date1 =new Date1();
// System.out.println(date2.a);
//System.out.println(date1.a);
date2.a();
}
}
//输出结果:30
注意:父类中private成员变量虽然在子类中不能直接访问,但是也继承到子类中去了。
四、final关键字
final int a = 10 ;a = 20 ; // 编译出错
final public class Animal {...}public class Bird extends Animal {...}// 编译出错Error :( 3 , 27 ) java : 无法从最终 com . bit . Animal 进行继续
五、继承与组合
汽车和其轮胎、发动机、方向盘、车载系统等的关系就应该是组合,因为汽车是有这些部件组成的。
// 轮胎类class Tire {// ...}// 发动机类class Engine {// ...}// 车载系统类class VehicleSystem {// ...}class Car {private Tire tire ; // 可以复用轮胎中的属性和方法private Engine engine ; // 可以复用发动机中的属性和方法private VehicleSystem vs ; // 可以复用车载系统中的属性和方法// ...}// 奔驰是汽车class Benz extend Car {// 将汽车中包含的:轮胎、发送机、车载系统全部继承下来}
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:jacktools123@163.com进行投诉反馈,一经查实,立即删除!
标签: