OOP语言(面向对象语言)特征:继承 封装 多态
继承:代码的复用 人——学生
1,派生类继承了基类的除了构造函数的其他数据成员
class Base1{//基类,父类
public int ma;//数据成员
static{
System.out.println("base.static innt!!!!");
}
{
System.out.println("base.instance innt!!!!");
}
public Base1(int a){
this.ma = a;
System.out.println("base init!!!");
}
public void sd(){
}
}
//子类 派生类
class Derive extends Base1{
static{
System.out.println(" Derive.static innt!!!!");
}
{
System.out.println(" Derive.instance innt!!!!");
}
private int mb;
public Derive(int a,int b){//报错!!!!!
System.out.println(" Derive innt!!!!");
this.mb = b;
}
}
2,super():调用基类的构造函数
private int mb;
public Derive(int a,int b){
super(a);//基类的构造函数 显示调用 第一行
this.mb = b;
System.out.println(" Derive innt!!!!");
}
super.data :访问基类的数据成员
public void fun(){
int w=super.ma;
super(.func():访问基类的成员方法
public void fun(){
super.sd();
int w=super.ma;
}
3,类------> 对象 初始化顺序
public class Test12 {
public static void main(String[] args) {
Base1 b = new Base1(12);
}
}
1,静态的数据成员和代码块
2,实例数据成员或实例代码块
3,调用合适的构造函数
4,派生类继承基类后的打印顺序:静态(只初始化一次)--->实例--->构造函数
public static void main(String[] args) {
Base1 b = new Base1(12);
System.out.println("-------------");
Derive d = new Derive(100,10);
}
5,基类成员在派生类中的访问权限
同包子类 同包非子类 不同包子类 不同包非子类
public 可以 可以 可以 可以
protected 可以 可以 可以 不可以
(包访问权限 继承当中)
private 不可以 不可以 不可以 不可以
默认权限 可以 可以 不可以 不可以
(包访问权限)
6,基类和派生类对象之间赋值
派生类对象可以赋值给基类,基类不能赋值给派生
public static void main(String[] args) {
Base1 b = new Base1(12);
Derive d = new Derive(100,10);
b = d;
//d = b;报错!!!!
Base1 b2 = new Derive(10,20);
//基类引用 引用了派生类对象
7,(反汇编的时候)
invokevirtual(java中除了构造函数和静态函数,其他成员函数都被处理为虚函数也就是这个英文)
invokestatic(静态函数)
8,派生类和基类同名方法的关系
overlode(重载)
函数名相同 参数列表不同 返回值无要求
override(重写/覆盖)
函数名相同 返回值 相同 参数列表相同
class Base{
private int ma;
public Base(int a){
this.ma = a;
}
public void fun1(){//实例方法
System.out.println("Base.fun1!!!");
}
public static void fun2(){//类方法
System.out.println("Base.fun2!!!");
}
}
class Derivel1 extends Base{
private int mb;
public Derivel1(int a,int b) {
super(a);
this.mb = b;
// TODO Auto-generated constructor stub
}
public void fun1(int i){//重载
System.out.println("derive1.fun1(int)!!");
}
}
class Derive2 extends Base{
private int mc;
public Derive2(int a,int c) {
super(a);
this.mc = c;
// TODO Auto-generated constructor stub
}
public void fun1(){//实例方法
System.out.println("Derive2.fun1!!!");
}
public static void fun2(){//类方法
System.out.println("Derive2.fun2!!!");
}
}
重载:
public static void main(String[] args) {
Base b = new Base(10);
Derivel1 d1 = new Derivel1(10,20);
d1.fun1();
d1.fun1(23);
}
重写
动态绑定 : 运行期间 new
静态绑定 : 编译期间 static 不需要对象
public static void main(String[] args) {
Base b = new Base(10);
Derive2 d2 = new Derive2(20,45);
Base b1 = new Derive2(203,4);
b1.fun1();
d2.fun1();
b.fun1();
}
反汇编的时候发现
b1.fun1()时它是显示Base.fun1()
但是为什么结果是Derive2.fun1!!!呢????
这个时候就是因为动态绑定
(编译期间不知道调用谁所以叫做动态绑定)
public static void main(String[] args) {
Base b = new Base(10);
Derive2 d2 = new Derive2(20,45);
Base b1 = new Derive2(203,4);
b1.fun1();
b1.fun2();
}
为什么b1.fun2()打印出来的是Base.fun2!!!呢???
这是因为方法表本身在编译期间产生,fun2是静态方法,它也在编译期间产生,所以不会发生动态绑定