Java继承
Posted biu嘟
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java继承相关的知识,希望对你有一定的参考价值。
一.继承
1.简介:
特点:利于代码复用;缩短开发周期。注:子类不能直接访问父类的私有属性
满足“A is a B”的关系就可以形成继承关系
例:
父类:
1 package com.swpu.animals; 2 3 public class Animal { 4 //属性 5 private String name; 6 private int month; 7 private String species; 8 public String getName() { 9 return name; 10 } 11 public void setName(String name) { 12 this.name = name; 13 } 14 public int getMonth() { 15 return month; 16 } 17 public void setMonth(int month) { 18 this.month = month; 19 } 20 public String getSpecies() { 21 return species; 22 } 23 public void setSpecies(String species) { 24 this.species = species; 25 } 26 27 public void eat(){ 28 System.out.println("吃东西了"); 29 } 30 31 }
子类:
1 package com.swpu.animals; 2 3 public class Dog extends Animal { 4 private int weight; 5 public void setWeight(int weight){ 6 this.weight=weight; 7 } 8 public int getWeight(){ 9 return this.weight; 10 } 11 public void run(){ 12 System.out.println("我是名叫"+this.getName()+"的"+this.getSpecies()+"在奔跑"); 13 } 14 15 }
2.方法重写:
语法规则:返回值类型,方法名,参数类型、顺序、个数都要和父类继承的方法相同。
注:方法重写必须要在有继承关系的子类中;
方法名相同,参数列表相同(参数顺序,个数,类型),方法返回值相同(可以允许是子类类型【向下兼容】);
方法的访问修饰符是可以允许有变化的,但是访问范围要大于等于父类的访问范围;
方法的重写与方法的参数名无关;
在Java中仅限方法重写,无属性重写,但是在子类中,可以定义与父类重名的属性的。
子类重写了父类的方法后,子类对象调用的是重写后的方法。
二.访问修饰符的分类与作用
private:只允许在本类中进行访问;
public:允许在任意位置访问;
protected:允许在当前类,同包子类/非子类,跨包子类访问,跨包非子类不允许;
默认:允许在当前类,同包子类/非子类;跨包子类/非子类不允许调用
三.super关键字:父类对象的引用
注:Python中super()是一个函数,并不是直接调用父类,而是根据MRO算法的调用顺序。
对比Python的继承初始化顺序(未调用super):父类的静态成员——>子类静态成员——>子类构造(实例化不会调用父类构造,调用super函数会遵照MRO【Pythoh3后是C3】算法的顺序调用)【注:如果是多继承则按照每个继承从父类往低层的顺序】
1.Java中的super:
访问父类成员方法:super.print();
访问父类属性:super.name;
访问父类构造方法:super()
Java中利用super关键字调用父类的方法和属性
父类的构造方法不允许被继承,不允许被重写,但是会影响子类对象的实例化(子类构造默认调用的是父类的无参构造)
2.继承的初始化顺序:
父类的静态成员(多个父类,从最顶层父类按顺序执行【注访问修饰符不影响成员的加载顺序,跟书写位置有关】)——>子类静态成员——>父类对象构造——>子类对象构造
注:子类构造默认调用的是父类的无参构造,可以通过super()调用父类允许被访问的其他构造方法【必须放在子类有效构造方法的第一行】
注意:
三.super和this对比
注:构造方法调用时,super和this不能同时出现(都要在第一行)
四.方法重写和方法重载的对比
五.Object类
1.Object中常用的方法:
1.1equals方法:
equals():直接继承Object中的equals()方法时,比较的是两个引用是否指向的是同一个对象(相当于Python中的is);
子类可以通过重写equals方法的形式,改变比较的内容;
如果是String中的equals(重写了Object中的equals,判断的是两个值是否相等)
重写equals:
1 package com.swpu.test; 2 import com.swpu.animals.Animal; 3 4 public class Test3 { 5 public static void main(String[] args){ 6 Animal one=new Animal("哈哈",20); 7 Animal two=new Animal("哈哈",20); 8 boolean flag=one.equals(two); 9 //==判断的是是否是同一空间 10 System.out.println("one 和 two的引用比较:"+flag); 11 System.out.println("one 和two 的引用比较:"+(one==two)); 12 String str1=new String("hello"); 13 String str2=new String("hello"); 14 boolean flag2=str1.equals(str2); 15 System.out.println("str1 和 str2的引用比较:"+flag2); 16 System.out.println("str1 和str2 的引用比较:"+(str1==str2)); 17 /** 18 * 输出: 19 * one 和 two的引用比较:false 20 one 和two 的值比较:false 21 str1 和 str2的引用比较:true 22 str1 和str2 的值比较:false 23 */ 24 25 } 26 27 28 }
1.2toString方法:
输出对象时,默认自动调用toString方法,相当于Python的__repr__或__str__魔法函数;
继承Object中的toString方法时,输出对象的字符串表现形式为:类型信息+@+地址信息(通过hash计算)【如:com.swpu.animals.Animal@15db9742】
重写toString方法:
1 //重写toString方法 2 public String toString(){ 3 return "姓名:"+this.getName()+"月份:"+this.getMonth(); 4 } 5
六.final关键字
final class:该类没有子类(public final class;final public class);
final 方法:该方法不允许被子类重写,但是可以被子类正常继承使用;
final 方法内局部变量:只要在具体被使用之前进行赋值即可,一旦赋值,不能进行修改;
final 类中成员属性:赋值场景:1.定义直接初始化;2.构造方法;3.构造代码块;
构造方法不允许用final修饰。
注:
基本数据类型的变量:初始赋值后不能被修改
引用数据类型:初始化之后不能在指向另一个对象,但对象的内容是可以变的;
final可以和static配合使用(方法,变量):通过final修饰可以提高性能,但会减低扩展性
七.注解介绍
以上是关于Java继承的主要内容,如果未能解决你的问题,请参考以下文章