java学习笔记(四)--(对象编程-类与方法)(super关键字&final关键字&多态性&实例方法与静态方法之间的关系)***重要***

super关键字

super表示调用父类方法

  • 调用父类构造方法 super(参数列表)

  • 当在子类中调用父类无参构造时,super(可写可不写)

  • 当子类调用父类有参构造时,super(参数列表)必须要写,告知编译器调用的是哪个父类有参构造  ******

  • super与this在构造方法中不能同时存在,即子类不存在构造方法的互相调用

super调用父类普通方法

  • super.方法名(参数列表)  明确表示调用父类中被覆写的方法

使用super调用父类的同名方法

class Person{
    public void print(){
        System.out.println("1.I am father");
    }
}
class Student extends Person{
    public void print(){
    //使用super.方法() 调用父类中被覆写的方法
    super.print();
        System.out.println("2.I am child");
    }
}
//主类
public class Test{
    //主函数
    public static void main(String[] args){
        new Student().print();
    }
}
//打印结果如下
//1.I am father
//2.I am child

super表示调用父类属性(了解)

//使用super调用父类属性
class Person{
    public String info ="爸爸!";
}
class Student extends Person{
    public String info ="儿子!";
    public void print(){
    //使用super.属性调用父类中的属性
        System.out.println(super.info);
        System.out.println(this.info);
    }
}
//主类
public class Test{
//主函数
    public static void main(String[] args){
        new Student().print();
    }
}
//打印结果如下
//爸爸
//儿子

this与super区别   ***重要***

this与super区别
  区别 this super
1

概念

访问本类中的属性和方法 访问父类中的属性和方法
2 查找范围 先查找本类,若本类没有就调用父类 不查找本类,直接调用父类定
3 特殊 表示当前对象

this与super使用举例

class Person {
    public static void prt(String s) {
        System.out.println(s);
    }
    Person() {
        prt("A Person.");
    }
    Person(String name) {
        prt("A person name is:" + name);
    }
}
class Chinese extends Person {
    Chinese() {
        super(); // 调用父类构造函数(1)
        prt("A chinese.");// (4)
    }
    Chinese(String name) {
        super(name);// 调用父类具有相同形参的构造函数(2)
        prt("his name is:" + name);
    }
    Chinese(String name, int age) {
        this(name);// 调用当前具有相同形参的构造函数(3)
        prt("his age is:" + age);
    }
}
public class Test{
    public static void main(String[] args) {
        Chinese cn = new Chinese();
        cn = new Chinese("Dyson");
        cn = new Chinese("Dyson", 22);
    }
}
// 打印结果如下
// A Person.
// A chinese.
// A person name is:Dyson
// his name is:Dyson
// A person name is:Dyson
// his name is:Dyson
// his age is:20

 

final关键字

  1. final修饰类:当一个类用final定义后,表示该类不允许被继承。同时,该类中的所有方法都会被隐式加上final关键字(不包括成员变量)

  2. final修饰方法:当一个方法被final关键字定义后,表示该方法不允许被覆写。final方法常用于模板方法---保护性

  3. final修饰属性:当属性被final修饰后,表示该属性值不可变。并且该属性必须要在声明时初始化,构造方法初始化,构造块初始化,否则就会编译出错

              a.final修饰基本数据类型变量(99%)

                      在类中的常量一般使用final+static,描述全局变量

                      全局常量命名规范:多个单词全大写,且单词间以_分隔

                      eg. public static final int MY_AGE = 10 ;

              b.final修饰引用数据类型变量(地址不可变)

String类以及8大数据类型包装类(Integer)都是final类---保护性

数据类型转化

在Java中当使用 +、-、*、/、%、运算操作时,遵循如下规则:

  • 只要两个操作数中有一个是double类型的,另一个将会被转换成double类型,并且结果也是double类型,如果两个操作数中有一个是float类型的,另一个将会被转换为float类型,并且结果也是float类型,如果两个操作数中有一个是long类型的,另一个将会被转换成long类型,并且结果也是long类型,否则(操作数为:byte、short、int 、char),两个数都会被转换成int类型,并且结果也是int类型。但是final修饰的域类型不会发生变化.

例题:请选出下面出错的语句  ***重要***

byte b1=1,b2=2,b3,b6,b8;    
final byte b4=4,b5=6,b7=9;   
public void test() {       
    b3=(b1+b2);  /*语句1*/        当执行语句1时,b1和b2都会被转化为int类型,当大类型赋值给小类型时必须要强转
    b6=b4+b5;    /*语句2*/        当执行语句2时,由于b4和b5都是被final修饰,所以他们的类型不会发生改变
    b8=(b1+b4);  /*语句3*/        理由同语句1
    b7=(b2+b5);  /*语句4*/        理由同语句1
    System.out.println(b3+b6);    
}

答案:只有语句2正确;

 

多态性

概念总结:

  • 对象多态性的核心在于方法的覆写

  • 通过对象的向上转型可以实现接收参数的统一,向下转型可以实现子类扩充方法的调用(一般不操作向下转型,有安全隐患)。

  • 两个没有关系的类对象是不能够进行转型的,一定会产生ClassCastException

多态:同一个类实例的相同方法在不同情况下有不同的表现形式

  • 向上转型(90%)核心用处参数统一化  ***重要***

            父类 父类引用 = new 子类();

            Person per =new Student();

不管是否发生了向上转型,核心本质还是在于:你使用的是哪一个子类(new在哪里),而且调用的方法是否被子类所覆写了,和覆写的结果差不多

class Person {
    public void print(){
        System.out.println("1.我是爸爸!");
    }
}
class Student extends Person {
    public void print(){
        System.out.println("2.我是儿子!");
    }
}
public class Test{
    public static void main(String[] args) {
        //向上转型
        Person per=new Student();
        per.print();
    }
}
//打印结果如下
//2.我是儿子!
  • 向下转型(1%)--需要强制类型转换-用于父类引用需要调用子类扩充方法时

             子类 子类引用  = (子类) 父类实例; 

             Student stu  = (Student) per;

        要发生向下转型,必须先发生向上转型(爹认儿子,亲子鉴定)

        在向下转型前先判断是否要要想上转型

      (运行时异常 RTTI) ClassCastException(类转型异常) :发生在两个不能强转的类之间

        引用 instanceof 类:表示该类引用能否指向该类实例 返回 boolean

        per instanceof Student

class Person {
    public void print(){
        System.out.println("1.我是爸爸!");
    }
}
class Student extends Person {
    public void print(){
        System.out.println("2.我是儿子!");
    }
    public void fun(){
        System.out.print("只有儿子有!");
    }
}
public class Test{
    public static void main(String[] args) {
        //向上转型
        Person per=new Student();
        per.print();
        //per一定是父类的对象,但不一定子类的对象,要先进行向下转型才能表示子类对象
        System.out.println(per instanceof Person);
        System.out.println(per instanceof Student);
        if (per instanceof Student) {
            //避免ClassCastException
            //强转
            Student stu = (Student) per ;
            stu.fun();
        }
        //强转
        // Student stu=(Student) per;
        //stu是子类引用不论是否转型,都既可以为父类的对象也是子类的对象
        // System.out.println(per instanceof Person);
        // System.out.println(per instanceof Student);
        // stu.fun();
    }
}

向上转型最核心用处 -- 参数统一化

class Person {
    public void print(){
        System.out.println("1.我是人类!");
    }
}
class Student extends Person {
    public void print(){
        System.out.println("2.我是学生!");
    }
}
class Worker extends Person {
    public void print(){
        System.out.println("3.我是工人!");
    }
}
public class Test{
    public static void main(String[] args) {
        //将对象向上转型
        whoYouAre(new Student());
        whoYouAre(new Worker());
    }
    public static void whoYouAre(Person per){
        per.print();
    }
}
// 打印结果如下
// 2.我是学生!
// 3.我是工人!

实例方法和静态方法之间的关系  ***重要*** 

  1. 静态方法只能访问静态成员,实例方法可以访问静态和实例成员。

  2. 静态方法在访问本类的成员时,只允许访问静态成员(即静态成员变量和静态方法),而不允许访问实例成员变量和实例方法;实例方法则无此限制

  3. 静态方法在程序初始化后会一直贮存在内存中,不会被垃圾回收器回收,非静态方法只在该类初始化后贮存在内存中,当该类调用完毕后会被垃圾回收器收集释放。

  4. 静态方法在初始化类时初始化,并分配内存;动态方法只有先创建类的实例对象后,才能调用动态方法

  5. 在外部调用静态方法时,可以使用"类名.方法名"的方式,也可以使用"对象名.方法名"的方式。而实例方法只有后面这种方式。也就是说,调用静态方法可以无需创建对象

猜你喜欢

转载自blog.csdn.net/ds19980228/article/details/83217637