何为继承
面向对象思想中提出了继承,专门用于共性抽取,实现代码复用。
简单来说就是有些代码之间有一些特性是共通的,为了解耦合以及减轻代码量,通常会把代码进行共性抽取。
父类与子类
封装共通特性、被继承的类称为父类,而继承共通特性的类称为子类。
子类继承父类的格式:
修饰符 class 子类 extends 父类{ 代码段 }
下列通过一个实例来深入体会父类与子类之间的关系。
例:
我们先定义一个类来描述狗的属性和行为
public class dog {
String name;
int age;
float weight;
String color;
public void bark(){
System.out.println(name+"正在叫....");
}
public void eat(){
System.out.println(name+"正在吃饭....");
}
}
然后再定义一个类来描述猫的属性和行为
public class cat {
String name;
int age;
float weight;
String color;
public void bark(){
System.out.println(name+"正在叫....");
}
public void eat()
{
System.out.println(name+"正在吃饭....");
}
}
通过比较我们可以发现,猫和狗这两个类之间的一些属性和行为有特性上的共通,我们可以写一个类命名为animal作为父类
public class animal {
String name;
int age;
float weight;
String color;
public void bark(){
System.out.println(name+"正在叫....");
}
public void eat()
{
System.out.println(name+"正在吃饭....");
}
}
在创建了父类之后,子类会将父类的成员属性和方法都继承到子类中,我们只需要子类进行实例化后,用子类对象. 就能访问子类从父类继承的成员属性和方法。
注:子类在进行继承之后要添加子类特有的成员变量或者重写成员方法,要突出与父类的不同,否则就没有必要进行继承
public class cat extends animal{
public void sleep(){
System.out.println(name+"正在睡觉....");
}
public static void main(String[] args) {
cat c1 = new cat();
c1.age=10;
c1.name="加菲";
c1.color = "橘色条纹";
c1.bark();
c1.eat();
}
}
1、父类和子类的成员变量访问
如果访问的成员变量父类和子类中都有定义,则优先访问子类的成员变量,
如果访问的成员变量继承自父类而子类中没有定义,则是访问父类中的成员变量,
如果访问的成员变量在父类和子类之中都没有定义,则会编译报错
用一句话概括:成员访问遵循就近原则
2、父类和子类的成员方法访问
父类和子类中同名的方法:
访问时要注意成员方法在子类中有无进行重写或者重载,那么根据具体需求选择具体的方法
父类和子类中不同名的方法:
具体应用具体访问,用对象.直接访问
super关键字
用途:
如果子类中有成员变量和父类成员变量同名,如何访问父类中的成员变量?
这时候要用到super关键字。Java中提供了super这么一个关键字,用于子类访问父类成员。
在调用子类构造方法时,子类继承的父类构造方法是否也会一起被调用呢?
答案是:会。
子类的成员组成分为两部分:子类本身就有的和继承自父类的 。
在创建子类对象的时候会先调用父类的构造方法,将子类从父类继承下来的成员进行构造,再调用子类的构造方法对新添加的成员进行初始化。
通过一个实例来理解:
先在一个包内创建一个类命名demo1
public class demo1 {
public demo1()
{
System.out.println("demo1()");
}
}
然后创建一个类命名demo2并且继承demo1 ,实例化demo2
public class demo2 extends demo1 {
public demo2(){
System.out.println("demo2()");
}
public static void main(String[] args) {
demo2 d2 = new demo2();
}
}
运行结果:
我们可以观察到:在demo2实例化对象的过程中调用了demo2的构造方法,因为类的继承,在调用demo2的构造方法之前先访问了demo1的构造方法
注意:super只能在非静态方法中使用。
super语句必须是子类构造方法里调用父类构造方法时的第一句语句(也就是super();必须是构造方法中的第一句语句)
如果父类构造方法没有带参数,子类构造方法中编译器会默认给子类的构造方法添加super();
如果父类构造方法有带参数,那么需要自己为子类构造方法添加super();,不然会发生编译报错
super();只在子类构造方法中出现一次,而且不能与this同时出现
与this的区别:
super与this都在成员方法中访问其它的成员变量和成员方法,但是二者既有相同点也有不同点。
相同点:
1、都是Java中的关键字
2、只能在非静态化的类中使用,用来访问非静态化的方法和字段
3、都必须是构造方法的第一句语句,且不能与对方同时存在
不同点:
1、this的引用是当前对象的引用,当前对象即调用实例方法的对象,而super()是当前对象继承自其父类的部分成员的引用
2、在构造方法中this(...)用于调用本类的构造方法,super(...)用于调用父类的构造方法
3、在非静态成员方法中:this用于访问本列的成员变量,super用于访问继承自父类部分的成员对象
4、super()在构造方法中不写编译器会默认添加,但是编译器不会默认添加this引用,一旦没有自己写this引用那就是没有
继承中的代码块执行顺序
1、最先执行的是静态代码块且静态代码块只执行一次
2、实例化代码块只有在创建对象的时候会执行
3、在执行实例化代码块之后,最后执行类的构造方法
实际顺序也就是:静态代码块>实例化代码块(要创建对象)>类的构造方法
下列通过实际代码直观感受一下:
创建父类,重写父类的构造方法,,写一段静态代码和一段非静态化代码
public class Dad { //创建父类
public String name;
public Dad(String name) {
this.name = name;
System.out.println("Dad:构造方法执行!");
}
{
System.out.println("Dad:实例代码块执行!");
}
static {
System.out.println("Dad:静态化代码块执行!");
}
}
创建子类继承父类
class Son extends Dad{ //子类继承
public Son(String name) {
super(name);
System.out.println("Son:构造方法执行!");
}
{
System.out.println("Son:实例代码块执行!");
}
static{
System.out.println("Son:静态化代码块执行!");
}
}
创建一个类进行实例化测试:
public class test {
public static void main(String[] args) {
Son s1 = new Son("张三");
}
}
结果:
由这个例子以及例子的结果我们可以知道:
在有继承关系的实例化对象中,代码的执行顺序为——父类静态代码块>子类静态代码块>父类的实例代码块>父类构造方法>子类的实例代码块>子类的构造方法
protected关键字
protected是对数据以及数据进行操作的方法进行封装的访问限定符,而封装的概念以及应用详情请移步上一篇博客:http://t.csdnimg.cn/EYVh1
父类中进行封装的代码无论访问权限如何,都会被子类给继承。
继承方式
java中有以下几种继承方式:
Java中唯独不支持多继承,一子不能有多父
注意:Java中即便支持多层继承,但是为了减小代码的复杂度,一般不超过三层继承关系。
本次博客分享到此为止啦!请不要吝啬您的三连哦!!