1.1继承的概念
继承是面向对象最显著的一个特性。继承是从已有的类中派生出新的类,新的类能吸收已有类的数据属性和行为,并能扩展新的能力和属性。
已有的类被称为父类或基类,新的类被称为子类或派生类。
继承最大的作用就是:共同代码的复用以及实现多态。
1.2继承的语法使用
java中使用继承需要借助关键字extends
//常用的继承格式
public class 子类 extends 父类{
//子类新增的属性和方法
}
例如:所有的动物都有名字,都有年龄,同时都会吃饭和睡觉,这些共同属性就可以写成父类,让各种动物来继承。猫会喵喵叫,狗会汪汪叫,这就是每个动物不同的地方,这些就是子类新增的属性,猫会抓老鼠,狗会看门,这是子类新增的方法。
//Animal.java
public class Animal {
//创建父类,动物
String name;
int age;
public void eat(){
//动物都会进食
System.out.println(name+"在吃饭");
}
public void sleep(){
//动物都会睡觉
System.out.println(name+"在睡觉");
}
}
//Dog.java
public class Dog extends Animal{
void bark(){
System.out.println(name+"汪汪汪~~");
}
}
//Cat.java
public class Cat extends Animal{
void bark(){
System.out.println(name+"喵喵喵");
}
}
//jicheng.java
//主函数
public class jicheng {
public static void main(String[] args) {
Dog dog1=new Dog();
//对象实例化
System.out.println(dog1.name);
System.out.println(dog1.age);
dog1.eat();
dog1.sleep();
dog1.bark();
}
}
运行结果:
1.3父类成员的继承和访问
在子类继承了父类的变量后,如果父类和子类有同名变量,那么在子类访问的时候优先访问的是子类自己的变量,如果子类中没有这个变量,则会在父类中进行查找,如果父类有则访问父类的变量。
注意:成员访问遵循就近原则,若子类中有就优先访问子类中的变量,若子类中没有的话就查询并访问父类中的变量。
//定义父类
public class father {
int a=11;
int b=22;
int d=33;
}
//定义子类
public class Son extends father {
char a ='a';
double b = 88;
float c = 77;
public static void main(String[] args) {
Son son1=new Son();
System.out.println(son1.a);
System.out.println(son1.b);
System.out.println(son1.c);
System.out.println(son1.d);
}
}
实际输出结果:
由此可验证以上结论。
1.3.1访问父类的成员方法
//定义父类
public class father {
public void test1(){
System.out.println("父类方法1");
}
public void test2(){
System.out.println("父类方法2");
}
}
//定义子类
public class Son extends father {
public void test1(){
System.out.println("子类方法1");
}
public static void main(String[] args) {
Son son1 = new Son();
son1.test1();
son1.test2();
}
}
实际输出结果:
由此可得:子类中访问父类中的成员方法时,如果方法同名,那么子类会优先访问自己的方法,若子类没有此方法,则在父类寻找并访问方法。
1.4super关键字
如果在子类中需要访问父类中同名的成员时,无法直接访问,此时就需要借助关键字super。
java中super关键字的主要作用:在子类方法中访问父类成员。
//定义父类
public class father {
int a;
int b;
public void test1(){
System.out.println("父类方法1");
}
public void test2(int a){
System.out.println("父类方法2");
}
}
//定义子类
public class Son extends father {
int a;
int b;
public void test1(){
System.out.println("子类方法1");
}
public void test2(){
System.out.println("子类方法2");
}
public void test3(){
a=10; //访问的是子类中的a,等价于this.a
super.a=20; //使用关键字super,访问的是父类中的a
test1();
super.test1();
test2(); //访问的是子类中的teat2()方法
test2(5); //访问的是父类中的test2()方法,虽然没有使用super
//但是参数不同,构成了重载
}
}
注意事项:super关键字只能在非静态中使用(例如:不能在static修饰的主函数中使用)
1.5子类的构造方法
子类在构造对象的时候,需要先调用父类中的构造方法。
//定义父类
public class father {
public father(){
System.out.println("父类构造方法");
}
}
//定义子类
public class Son extends father {
public Son(){
//super();
//此时会默认调用父类的无参构造方法,在第一行默认输入super();
System.out.println("子类构造方法");
}
}
//实例化子类
public class Test {
public static void main(String[] args) {
Son son=new Son();
}
}
实际输出:
注意事项:
1.父类构造方法无参或是默认构造方法时,在子类构造方法的第一行会默认调用super();调用父类的构造方法。
2.如果父类的构造方法含参,那子类就不能使用默认的构造方法,需要自己选择适合的构造方法,否则编译失败。
3.子类构造方法中使用super()调用父类构造时,必须是子类构造方法的第一句。
4.在子类构造方法中,super()只能出现一次,并且和this()不能同时出现。
1.6继承中的顺序
1、父类静态代码块优先于子类静态代码块执行,且是最早执行。
2、父类实例代码块和父类构造方法紧接着执行。
3、子类的实例代码块和子类构造方法紧接着再执行。
4、第二次实例化子类对象时,父类和子类的静态代码块都将不会再执行
1.7protected关键字
限定符的作用:类或类中的成员能否在类外或其他包中访问
各关键字的权限:
注意:java不支持多继承
1.8final关键字
final关键字可以用来修饰变量、成员方法以及类。
1.8.1修饰变量
final关键字修饰变量或字段,表示常量,即不可更改
final int a=20;
a=10; //编译出错
1.8.2修饰类
final关键字修饰类表示此类不可被继承
final public class Father{
//..........
}
public class Son extends Father{
//..........
}
//编译出错,无法继承
1.8.3修饰方法
final关键字修饰方法表示此方法不能被重写
1.9组合和继承
注意:在编写代码的时候尽量做到多用组合、少用继承