目录
一,继承的理解
首先引入两个概念,父类和子类,子类拥有父类的所有属性和方法
继承操作,就是将两个类以父类和子类的关系联系起来
二,语法格式
class parents{//这是父类
int age;
String name;
}
class son extends parents{//子类extends(继承)父类
//此时,son类中并无任何属性和方法
//但是用son类实例化的对象,一定拥有parents类的所有属性和方法
}
三,示例用来理解
①创建一个Animal类和Dog类,Dog和Animal类以extends联系后,用Dog类实例化的对象d就拥有了Animal类中的属性
public class Main {
public static void main(String[] args) {
Dog d = new Dog();
d.age = 12;
d.name = "牧羊犬";
System.out.println("姓名为:" + d.name + ",年龄为:" + d.age);
}
}
class Animal{//这是父类
int age;
String name;
}
class Dog extends Animal{//子类extends(继承)父类
}
②在子类中,只允许直接访问父类中非private的属性和方法,换句话说,父类中private修饰的属性和方法在子类中无法直接访问,但是可以用getter和setter方法间接访问
class Animal{//这是父类
private int age;
public int getAge(){
return age;
}
String name;
}
class Dog extends Animal{//子类extends(继承)父类
String color;
void print(){
System.out.println(age);//直接访问父类中的private属性,错误!
System.out.println(name);//父类中的name为default权限,可以访问
}
}
四, 子类在父类基础上扩充属性和方法
子类已经拥有父类的所有属性和方法,扩充子类的属性和方法,让子类描述的对象更加具体
如下。Dog类示例化的对象首先会拥有Animal类的两个属性,并在此基础上扩充了一个属性
class Animal{//这是父类
int age;
String name;
}
class Dog extends Animal{//子类extends(继承)父类
String color;
}
五,对子类继承自父类的方法进行重写(override)
在Java中,子类可以重写父类的方法,但是必须满足以下条件:
- 方法名、参数列表必须与父类方法完全相同。
- 返回类型必须与父类方法相同或者是其子类。
- 访问权限不能比父类方法更严格(例如,如果父类方法是public,那么子类重写的方法也必须是public)。
①子类继承父类的方法,可以对继承过来的方法进行重写,重写后,用子类实例化的对象调用该方法时,将使用子类中重写的方法,而不是父类中的方法
public class Main {
public static void main(String[] args) {
Dog d = new Dog();
d.shout();
}
}
class Animal{//这是父类
int age;
String name;
void shout(){
System.out.println("发出了奇怪的叫声");
}
}
class Dog extends Animal{//子类extends(继承)父类
String color;
void shout(){
System.out.println("发出了汪汪汪的叫声");
}
}
②重写方法时需要注意,子类中重写的方法权限不得低于父类中原方法的权限!如下是错误例子!
class Animal{//这是父类
int age;
String name;
public void shout(){//父类该方法权限为public
System.out.println("发出了奇怪的叫声");
}
}
class Dog extends Animal{//子类extends(继承)父类
String color;
private void shout(){//子类该方法权限为private,低于父类中的public,错误!!!
System.out.println("发出了汪汪汪的叫声");
}
}
六,继承与构造
①用子类子类示例化对象时,会默认调用父类中的无参构造(相当于一个隐式super())
public class Main {
public static void main(String[] args) {
Son s = new Son();//子类示例化对象,一定会调用父类中的无参构造
}
}
class Parent{//这是父类
Parent(){
System.out.println("父类中的无参构造被调用");
}
}
class Son extends Parent{//子类extends(继承)父类
}
②super关键字
用super(参数1,参数2,参数3...)显式调用父类中的构造方法,这里的参数列表对应父类中的想调用的构造方法的参数列表
区分于this(),this()是用来在同一个类中的A构造方法里调用B构造方法
class Parent{//这是父类
int m_a;
Parent(){
System.out.println("父类中的无参构造被调用");
}
Parent(int m_a){
System.out.println("父类中的有参构造被调用");
this.m_a = m_a;
}
}
class Son extends Parent{//子类extends(继承)父类
Son(){
super(1027);
}
}
七,final关键字
- 修饰变量:如果一个变量被声明为
final
,那么它不能被重新赋值(=)。也就是说,它是一个常量,其值一旦被设定后就不能改变。 - 修饰类:如果一个类被声明为
final
,那么这个类不能被继承(extends)。也就是说,它是一个最终的类,不能有子类。 - 修饰方法:如果一个方法被声明为
final
,那么这个方法不能被重写(override)。也就是说,它是一个最终的方法,不能被其他类中的方法覆盖。 - 修饰属性:如果一个类的属性被声明为
final
,那么这个属性不能被继承或修改。也就是说,它是一个最终的属性,不能被其他类中的属性覆盖或修改。
class Animal{
public final void shout(){
}
}
class Dog extends Animal{
public void shout(){//重写父类中final修饰的方法,错误!!!
}
}
八,抽象类(abstract修饰)
用abstract修饰的类是抽象类
抽象类是一个不能被实例化的类,通常用于作为其他子类的基类。使用abstract
关键字修饰的类表示该类是抽象类。抽象类可以包含抽象方法、非抽象方法和字段。抽象方法是没有具体实现的方法,只有方法声明而没有方法体。
抽象类的子类必须实现所有的抽象方法才能被实例化,如果子类没有实现所有抽象方法,那么子类仍为抽象类,是无法实例化对象的!
注意点:
①含有抽象方法的类,必须是抽象类,也就是说,用abstract修饰的类,才能拥有abstract修饰的抽象方法
②抽象方法不能有方法体,也就是说,抽象类的抽象方法只能继承给子类,由子类来实现
③子类必须实现父类的所有抽象方法后才能实例化对象,否则该子类仍为抽象类
④抽象类不得用final修饰,因为final修饰的类不可被继承,这样和第③点矛盾
abstract class Animal{
abstract void shout();//抽象方法
}
class Dog extends Animal{
void shout(){//子类继承父类抽象方法并实现
System.out.println("汪汪汪");
}
}