前言
继承,是面向对象的三大特征之一。通过继承,子类获得父类的部分成员变量和方法,从而降低了整体代码的冗余。而子类可以获得父类哪些的方法和数据呢,如何改进父类的方法呢?今天我们开始学习有关Java继承的知识。
正文
一、认识继承
1、继承的概念
继承是Java面向对象的三大特折之一。
继承就是子类继承父类的特征与行为,使得子类拥有父类的实例域和方法,或子类从父类继承的方法,使得子类具有父类相同的行为。
例子:汽车是交通工具,汽车具备了交通工具的特点,是一种出行工具……
2、继承的书写格式
继承是通过关键字 extends 来将两个类进行串联,构建父子关系。 extends 的意思就是 继承。
// 修饰符 class 子类 extends 父类 { }
class Teacher extends People {
}
3、继承可调用的内容
继承中,子类调用父类中的方法与成员变量的范围取决于父类对方法、变量的限定。
①父类的静态方法/静态成员变量军部可以被调用。
②父类的构造器无法被继承
public class Test {
public static void main(String[] args) {
Teacher t = new Teacher();
//t.a = 10;//私有属性无法无法被子类继承
t.b = 20;
t.walk();
//t.run();//私有方法无法被子类继承
}
}
class People {
private int a;
int b;
private void run() {
}
public void walk() {
}
}
class Teacher extends People {
}
4、继承的特点与好处
特点:
两个类建立了父子关系后,子类可以访问父类中非私有的成员变量、成员方法。当我们访问子类时,Java会用子类与父类共同建设类的对象,而我们可以访问的对象,则是有子类和父类共同决定的。
优点:
减少的代码的冗余,提高了代码的复用性。当我们构建多个类时,发现这些类有一部分的内容完全一样,我们可以提取这部分内容出来,建设一个父类,减少代码的冗余。
public class Demo01 {
public static void main(String[] args) {
Teacher t = new Teacher();
t.name = "张三";
t.sleep();
t.eat();
t.work();
Coder c = new Coder();
c.name = "李四";
c.sleep();
c.eat();
c.work();
}
}
//请使用继承定义以下类:
//程序员(Coder)
// 成员变量: 姓名,年龄
// 成员方法: 吃饭,睡觉,敲代码
//
//老师(Teacher)
// 成员变量: 姓名,年龄
// 成员方法: 吃饭,睡觉,上课
/*
题目中两个类的成员变量都是年龄与年纪、成员方法都有相同的方法吃饭与睡觉,这些相同的变量和方法我们都可以提取出来,闯将一个父类People,减少冗余。
*/
class People {
String name;
int age;
public void eat() {
System.out.println(name + "eating");
}
public void sleep() {
System.out.println(name + "sleep");
}
}
class Coder extends People {
public void work() {
System.out.println(name + "敲代码");
}
}
class Teacher extends People {
public void work() {
System.out.println(name + "上课");
}
}
二、继承的注意事项
1、权限修饰符
权限修饰符是一种对代码适用范围进行限制的修饰符,一共有四个分别为:private、缺省、protected、public
权限修饰符 | 适用范围 |
---|---|
private | 私有的;仅在本类可用 |
缺省 | 在本类、同一个包下的类可以使用 |
protected | 在本类、同一个包下的类、子孙类可以使用 |
public | 所有的类都可以调用 |
范围由小到大排序:private < 缺省< protected<public
2、继承体系
继承的关系只能是单继承。原因是,如果存在多继承是,多个父类中出现一样的方法时,子类的调用就会报错,Java无法识别子类调用的是哪个父类的方法,所以Java则可以单继承。
继承只支持单继承,同时也支持多层继承。Object类 是所有类的父类或者其子孙类。
3、方法重写
有时候子类不满足父类的方法,在自己的类中建立了一个与父类一摸一样的类,并且重新定义方法的内容。这一种行为就是方法重写。
class People {
public void peo() {
System.out.println("干活");
}
}
class Teacher extends People {
@Override
public void peo(){
System.out.println("教书");
}
}
在方法重写时,Java提供了一个检验我们是否重写正确的功能 :@Override;当我们的重写格式不正确时,@Override会报错。不写不会影响代码的运行。
4、继承中成员的访问方式
①继承关系的成员的访问
原则:就近原则。优先在子类方法中寻找变量,其次在子类的成员变量中 寻找,最后才是在父类中寻找
public class Test {
public static void main(String[] args) {
Teacher t = new Teacher();
t.A();
}
}
class People {
int a = 100;
}
class Teacher extends People {
int a = 10;
void A() {
int a = 1;
System.out.println("a" + a);// 就近原则,输出----> 1
System.out.println("子类的成员变量中的a" + this.a);// this.变量名表示子类的成员变量 输出----> 10
System.out.println("父类的成员变量中的a" +super.a);// this.变量名表示父类的成员变量 输出----> 100
}
}
②继承关系的构造器的访问
调用super(XXX)调用父类的构造器,主要目的是为了给父类的成员变量赋值。
public class Test {
public static void main(String[] args) {
Teacher t = new Teacher();
System.out.println(t);//先打印哈哈,再打印地址
}
}
class People {
private int a;
public People(int a) {
this.a = a;
}
public People() {
System.out.println("哈哈");
}
public int getA() {
return a;
}
public void setA(int a) {
this.a = a;
}
}
class Teacher extends People {
private int b;
public Teacher(int a, int b) {
super(a);
this.b = b;
}
public Teacher() {
}//默认调用了super(),通过父类的无参构造对父类的成员变量进行赋值。
}
兄弟构造器之间的访问:this()
class Teacher extends People {
private int b;
private int c;
public Teacher(int b) {
this.b = b;
}
public Teacher(int b, int c) {
this(b);
this.c = c;
}
}
总结
有关Java的继承就到这里了,希望可以帮助到刚入门的朋友们,也欢迎大佬进来点评不足。