1.extends(继承):
1)提高了代码的复用性
2)让类与类之间产生了关系,为多态提供了前提
单继承:一个类只能有一个父类
多继承:一个类可以有多个父类,java不直接支持,虽能让子类具备更多的功能,但会产生方法调用的不确定性
当事物之间存在着所属关系时,可以通过继承体现这个关系(子类应具备父类的所有属性和行为)
都是由子类的共性抽取出来产生了父类,再让子类继承父类。
对于父类中私有的部分,子类不能直接访问,但子类具有该属性,只是没有访问权限,因为private降低了访问权限
class Father{
int num1 = 1;//父类成员变量
}
class Son extends Father{
int num2 = 2;//子类成员变量
public void show(){
int num3 = 3;//子类局部变量
System.out.println(num1);
System.out.println(num2);
System.out.println(num3);
}
}
class ExtendsDemo{
public static void main(String[] args){
Son s = new Son();
s.show();//1 2 3
}
}
2.当父类成员变量、子类成员变量和局部变量重名时的访问(super):
class Father{
int num = 1;//父类成员变量
}
class Son extends Father{
int num = 2;//子类成员变量
public void show(){
int num = 3;//子类局部变量
System.out.println(num);//输出局部变量num
System.out.println(this.num);//输出子类成员变量
System.out.println(super.num);//输出父类成员变量
}
}
class ExtendsDemo{
public static void main(String[] args){
Son s = new Son();
s.show();//3 2 1
}
}
3.this和super的区别:
this代表子类对象的引用
super代表父类的那片存储空间,而非父类对象的引用
4.子父类出现相同(返回值类型、函数名、参数列表都相同,区别于重载)方法,称为覆盖(override)
那么子类对象运行的是子类的方法。可通过super.来调用父类的方法
覆盖的作用:子类继承父类的功能,功能声明不变,但在子类中重新定义功能的内容,(这就是在原来的基础上升级)
class Father{
public void call(){
System.out.println("call");
}
public void sendMessage(){
System.out.println("Message");
}
public void show(){
System.out.println("name");
}
}
class Son extends Father{
public void show(){
super.show();//调用父类的show功能
System.out.println("number");
System.out.println("picture");
}//子类中覆盖父类的show方法,新增功能
}
class ExtendsDemo{
public static void main(String[] args){
Son s = new Son();
s.show();
}
}
覆盖的注意事项:
1)子类方法覆盖父类方法,必须保证子类方法的权限大于或等于父类方法的权限(public>(空 即默认)>private )
2)静态方法只能覆盖静态方法,或被静态覆盖
5.子类对象实例化的过程:
子类中所有构造函数的第一行默认都有一个隐式的super();语句,super()即是调用父类的空参数构造函数,因此创建子类对象时,父类的空参数构造函数都会运行。
调用本类中的构造函数用this(实参列表)语句,调用父类中的构造函数用super(实参列表)
注意:当父类中没有空参数构造函数时,子类需要通过显示定义super语句指定要访问的父类中的构造函数。(当没有写任何构造函数时,类中有默认的隐式空构造函数)
用来调用父类构造函数的super语句在子类构造函数中必须定义在第一行,因为父类的初始化要先完成。
pro1:this和super用于调用构造函数,不可以同时存在,因为他们必须定义在第一行,因为初始化动作要先执行。且子类中的对象必须先通过父类初始化。
class Father{
Father(){//super()
System.out.println("Father run");
}
Father(int x){//super()
System.out.println("Father run...."+x);
}
}
class Son extends Father{
Son(){//super()
// this(6);//调用子类构造函数Son(int x)进行初始化,在Son(int x)中还是会调用super()进行父类构造函数的初始化
super(6);//调用指定的父类构造函数Father(int x)进行初始化
System.out.println("Son run");
}
Son(int x){//super()
System.out.println("Son run...."+x);
}
}
class ExtendsDemo{
public static void main(String[] args){
Son s = new Son();
}
}
super(6):
this(6):
6.简单练习
class Person{
private String name;
private int age;
Person(String name,int age){
this.name = name;
this.age = age;
}
public void setName(String name){
this.name = name;
}
public String getName(){
return name;
}
public void setAge(int age){
this.age = age;
}
public int getAge(){
return age;
}
}
class Student extends Person
{
Student(String name,int age){
super(name,age);//直接调用父类的构造方法初始化子类对象
}
void study(){
System.out.println("studing...");
}
}
class Worker extends Person
{
Worker(String name,int age){
super(name,age);//直接调用父类的构造函数初始化子类对象
}
void work(){
System.out.println("working...");
}
}
class Demo{
public static void main(String[] args){
Student s = new Student("xiaoxu",21);
Worker w = new Worker("xiaoming",22);
System.out.println(s.getName()+":"+s.getAge());
w.setName("xiaomao");
w.setAge(22);
System.out.println(w.getName()+":"+w.getAge());
}
}
7.final
final:最终
1)final修饰符,可以修饰类、修饰方法、修饰变量
2)final修饰的类不可以被继承(防止子类覆盖父类的方法)
3)final修饰的方法不可以被覆盖
4)final修饰的变量,是一个常量,只能赋值一次,final double PI = 3.14;变量名需全部大写,用_连接
5)final修饰成员变量,需显示初始化:public static final NUM = 5;