面向对象编程有三大特性:封装、继承、多态。
多态存在的三个必要条件:
一要有继承
二要有重写
三父类引用指向子类对象
下面通过代码的形式了解继承的特性
这是我写的Father父类
public class Father {
int money = 10;
private int age = 33;
public Father() {
System.out.println("我是父类的构造方法");
}
public void eat(){
System.out.println("我是爸爸,我在吃饭");
}
protected void watch(){
System.out.println("我是爸爸,我在吃饭");
}
public void GetAge(){
System.out.println("我是爸爸,我的年龄是"+this.age);
}
}
Son1继承了Facher作为子类
public class Son1 extends Father{
int money = 100;
public Son1() {
System.out.println("我是儿子1的构造方法");
}
public void eat(){
System.out.println("我是儿子1,我在吃饭");
}
protected void watch(){
System.out.println("我是儿子1,我在吃饭");
System.out.println(super.money);
}
public static void main(String[] args) {
Son1 son1 = new Son1();//我是父类的构造方法 我是儿子1的构造方法
son1.watch();//我是儿子1,我在吃饭 10
System.out.println(son1.money);//100
}
}
Son1继承了Facher作为子类
public class Son2 extends Father{
int money = 100;
public Son2() {
System.out.println("我是儿子2的构造方法");
}
public void eat(){
System.out.println("我是儿子2,我在吃饭");
}
protected void watch(){//保护方法也可以被重写
System.out.println("我是儿子2,我在吃饭");
}
public static void main(String[] args) {
Son2 son2 = new Son2();//我是父类的构造方法 我是儿子2的构造方法
System.out.println(son2.money);//100
son2.GetAge();//我是爸爸,我的年龄是33
}
}
(1) 父类与子类之间的多态性,对父类的函数进行重新定义。如果在子类中定义某方法与其父类有相同的名称和参数,我们说该方法被重写 (Overriding)。在Java中,子类可继承父类中的方法,而不需要重新编写相同的方法。
但有时子类并不想原封不动地继承父类的方法,而是想作一定的修改,这就需要采用方法的重写。
方法重写又称方法覆盖。
(2)若子类中的方法与父类中的某一方法具有相同的方法名、返回类型和参数表,则新方法将覆盖原有的方法。
如需父类中原有的方法,可使用super关键字,该关键字引用了当前类的父类。
(3)子类函数的访问修饰权限不能少于父类的;
子类会继承父类的属性
1. 但是父类的属性如果私有了 不能直接访问到了 必须通过set get方法才可以访问到父类中的属性
2. 如果子类和父类具有相同的属性的时候 优先访问自己的 但是想要拿到父类的属性的时候 super获取到父类中的属性
构造函数(无法重写父类构造函数)
1.当子父类都有构造函数的时候 先执行父类的 因为子类构造函数中第一句都有一个默认的super隐式的 无参的情况
2.为啥要去初始化父类的构造函数呢? 因为初始化的时候可能会用到父类的属性和方法
public class aa {
int a;
public aa(int a) {
// TODO Auto-generated constructor stub
this.a = a;
System.out.println("我是aa的构造函数");
}
public void showA(){
System.out.println("我是aa的showA方法");
}
static {
System.out.println("我是aa的静态方法");
}
}
对于静态,当类加载成字节码文件后,只会执行一次
public class bb extends aa{
int b;
public bb(int a,int b) {
super(a);
this.b = b;
System.out.println("我是bb的构造函数");;
// TODO Auto-generated constructor stub
}
public void showB(int a){
System.out.println("我是bb的showB方法");
}
public void showA(int a){
System.out.println("我重写了showA方法"+a);
}
public static void main(String[] args) {
bb b = new bb(1, 2);//我是aa的静态方法(第一次会被调用) 我是aa的构造函数 我是bb的构造函数
bb c = new bb(1, 2);//我是aa的构造函数 我是bb的构造函数
b.showA(4);//我重写了showA方法4
b.showA();//我是aa的showA方法
b.showB(3);//我是bb的showB方法
}
}
当子类和父类具有相同参数的构造函数
1. 子类还是会隐式调用父类的无参构造函数的
2. 显示的书写super构造函数 默认调用父类无参的那个就不会添加了