精华内容
下载资源
问答
  • Java学习之九 Java方法 与Java多态(重写、重载) Java方法 java方法是语句的集合,在一起执行一个功能。 方法是解决一类问题的步骤的有序组合 方法包含于类或对象中 方法在程序中被创建,在其他地方被引用 ...

    Java学习之九 Java方法 与Java多态(重写、重载)

    Java方法

    java方法是语句的集合,在一起执行一个功能。

    • 方法是解决一类问题的步骤的有序组合
    • 方法包含于类或对象中
    • 方法在程序中被创建,在其他地方被引用

    方法的优点

    • 增加可读性,使程序变得简短而清晰
    • 有利于程序维护
    • 可以提高开发效率
    • 提高了代码重用性

    方法的命名规则

    • 以小写字母作为开头,后面的单词则用大写字母开头,不使用连接符。如addData()
    • 下划线可能出现在JUnit测试方法名称中用以分隔名称的逻辑组件。如testData_emptyStack

    方法的定义

    修饰符  返回值类型 方法名(参数类型 参数名){
        ...
    
        方法体
        ...
    
        return 返回值;
    }

    方法包含一个方法头和一个方法体:

    • 修饰符:修饰符,可选,告诉编译器是如何调用该方法。定义了该方法的访问类型
    • 返回值类型:方法可能会返回值。returnValueType是方法返回值的数据类型。有些方法执行所需的操作,但没有返回值。这种情况下,returnValueType是关键字void
    • 方法名:是方法的实际名称。方法名和参数表共同构成方法的签名
    • 参数类型:当方法被调用时,传递值给参数。这个值被称为实参或变量。参数列表是指方法的参数类型、顺序和参数的个数。参数是可选的,方法可以不包含任何参数。
    • 方法体:方法体包含具体的语句,定义改方法的功能。

    命令行参数的使用

    命令行参数是在执行程序时紧跟在程序名字后面的信息。

    如:$javac CommandLine.java

           $java CommandLine this is a command line 200 -100

    构造方法

    当一个对象被创建的时候,构造方法用来初始化该对象。构造方法与它所在类的名字相同,但构造方法没有返回值。

    Java自动提供了一个默认的构造方法。默认构造方法的访问修饰符和类的方位修饰符相同。不过如果你定义了自己的构造方法,默认构造方法就会失效。

     

    可变参数

    JDK1.5开始,Java支持传递同类型的可变参数给一个方法。

    在制定参数类型后面加一个省略号(...),声明如下:

    typeName... parameterName

    一个方法只能指定一个可变参数,他必须是方法的最后一个参数。任何普通的参数必须在可变参数之前声明。

     

    finalize()方法

    Java允许定义这样的方法,他在对象被垃圾收集器析构(回收)之前调用,这个方法叫做finalize().他用来清楚回收对象。

    如:你可以使用finalize()来确保一个对象打开的文件被关闭了。

    在finalize()方法里,你必须制定对象销毁时候要执行的操作。

    finalize()一般格式是:

    protected void finalize()
    {
    //在这里终结代码
    }

    Java多态

    多态是同一个行为具有多个不同表现形式或者形态的能力

    多态就是同一个接口,使用不同的实例而执行不同的操作

    多态的优点:

    • 消除类型之间的耦合关系
    • 可替换性
    • 可扩充性
    • 接口性
    • 灵活性
    • 简化性

    多态存在的三个必要条件

    • 继承
    • 重写
    • 父类引用指向子类对象
    Parent P= new Child();

    当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误;如果有,再去调用子类的同名方法。

    虚函数

    Java中没有虚函数的概念。虚函数就是为了多态存在的。Java的普通函数就相当于C++的虚函数,动态绑定是java的默认行为。如果java中不希望某个函数具有虚函数特性,可以加上final关键字变成非虚函数。

    重写(Override)

    子类能够重写父类的方法

    当子类对象调用重写的方法时,调用的是子类的方法,而不是父类中被重写的方法。

    子类如果想调用父类中被重写的方法,则必须使用关键字super

    重写是子类对父类的允许访问的方法的实现过程进行重新编写,返回值和形参都不能改变。即外壳不变,核心重写。

    重写方法不能抛出新的检查异常或者比被重写方法申明更加宽泛的异常。

    方法的重写规则

    • 参数列表必须完全与被重写的方法相同
    • 返回类型与被重写方法的返回类型可以不相同,但是必须是父类返回值的派生类
    • 访问权限不能比父类中被重写的方法的访问权限更低。如父类的一个方法被声明为public,那么在子类中重写该方法就不能声明为protected
    • 父类的成员方法只能被它的子类重写
    • 声明为final的方法不能被重写
    • 声明为static的方法不能被重写,但是能够被再次声明
    • 子类和父类在同一个包中,那么子类可以重写父类所有方法,除了声明为private和final的方法。
    • 子类和父类不在同一个包中,那么子类只能够重写父类的声明为public和protected的非final方法
    • 重写的方法能够抛出任何非强制异常,无论被重写的方法是否抛出异常。但是,重写的方法不能抛出新的强制性异常,或者比被重写方法声明的更广泛的强制性异常,反之则可以。
    • 构造方法不能被重写
    • 如果不能继承一个方法,则不能重写这个方法

    重载(Overload)

    重载是在一个类里面,方法名相同,而参数不同。返回类型可以相同也可以不相同

    每一个重载的方法(或者构造函数)都必须有一个独一无二的参数类型列表。

    重载规则

    • 被重载的方法必须改变参数列表(参数个数或类型不一样)
    • 被重载的方法可以改变返回类型
    • 被重载的方法可以改变访问修饰符
    • 被重载的方法可以声明新的或者更广的检查异常
    • 方法能够在同一个类中或者在一个子类中被重载
    • 无法以返回值类型作为重载函数的区分标准

    重写 overrid 与重载overload 的区别

    区别 重载方法 重写方法
    参数列表 必须修改 一定不能修改
    返回类型 可以修改 一定不能修改
    异常 可以修改 可以减少或删除,一定不能抛出新的或者范围更广的异常
    访问 可以修改 一定不能做更严格的限制,可以降低限制

    方法的重写和重载是Java多态性的不同表现,重写是父类与子类之间的多态性的一种表现。

    重载可以理解成多态的具体形式。

    • 方法重载是一个类中定义了多个方法名相同,而他们的参数的数量不同或者数量相同而类型和次序不同,则称为方法的重载。
    • 方法重写是子类存在与父类方法的名字相同、参数与返回值也一样的方法,就成为重写
    • 方法重载是一个类的多态性表现,而方法的重写是子类与父类的一种多态性表现。

     

     

     

    展开全文
  • Java基础】2.多态

    2020-05-05 17:57:59
    多态英文单词为 Polymorphism 一般简称Multi 面向对象三大特征:封装性、继承性、多态性 extends继承或者implements实现,是多态性的前提 代码中若要体现多态性,简而言之就是: ​ 父类引用子类对象,即子类对象被...

    【Java基础】2.多态

    2.1概述

    多态英文单词为 Polymorphism

    一般简称Multi

    面向对象三大特征:封装性、继承性、多态性

    extends继承或者implements实现,是多态性的前提

    在这里插入图片描述

    代码中若要体现多态性,简而言之就是:

    ​ 父类引用子类对象,即子类对象被当做父类看待

    格式:

    父类名称 对象名 = new 子类名称();

    或者

    接口名称 对象名 = new 实现类名称()

    2.2访问成员变量

    1.直接通过对象名称访问成员变量:

    ​ 看等号左边是谁,优先用谁,没有则向上找。

    2.间接通过成员方法访问成员变量:

    ​ 看该方法属于谁(对象),优先用谁,没有则向上找。

    2.3使用成员方法

    在多态的代码中,成员方法的访问规则是:

    ​ 看new的是谁,就优先用谁,没有则向上找。

    口诀:编译看左边,运行看右边

    对比:

    成员变量:编译看左边,运行还看左边;

    成员方法:编译看左边,运行看右边;

    2.4多态的用途

    在这里插入图片描述

    2.5对象向上转型

    对象的向上转型:其实就是多态写法

    格式:父类名称 对象名 = new 子类名称();

    含义:右侧创建子类对象,把它当做父类看待和使用。

    注意事项:

    1.向上转型一定是安全的。从小范围转向了大范围。

    2.弊端:一旦向上转型,就无法调用子类本来的特有内容。

    2.6对象向下转型

    对象的向下转型:其实是向上转型的逆操作

    格式:子类对象 对象名 = (子类名称) 父类对象; 类似于“强制类型转换”

    含义:将父类对象,【还原】成本来的子类对象

    注意事项:

    ​ 1.必须保证对象本来创建时,就是猫,才能向下转型成为猫。

    ​ 2.如果对象创建的时候,本来不是猫,强行向下转型成为猫,就会报错。ClassCastException

    2.7 instanceof关键字

    如何知道一个父类引用的对象,本来是什么子类?

    格式: 对象 instanceof 类名称

    这将会得到一个boolean值结果,也就是判断前面的对象能不能当做后面类型的实例

    2.8接口多态的综合案例

    2.8.1笔记本电脑

    笔记本电脑(laptop)通常具备使用USB设备的功能。在生产时,笔记本都预留了可以插入USB设备的USB接口,但具体是什么USB设备,笔记本厂商并不关心,只要符合USB规格的设备都可以。

    定义USB接口,具备最基本的开起功能和关闭功能。鼠标和键盘要想再电脑上使用,那么鼠标和键盘也必须遵守USB规范,实现USB接口,否则鼠标和键盘生产出来也没法使用。

    2.8.2案例分析

    进行描述笔记本类,实现笔记本使用USB鼠标、USB键盘

    • USB接口:包含设备功能、关闭设备功能
    • 笔记本类:包含开机功能、关机功能、使用USB设备功能
    • 鼠标类:要实现USB接口,并具备点击的方法
    • 键盘类:要实现USB接口,具备敲击的方法

    2.8.3案例实现

    在这里插入图片描述

    代码实现:

    ``

    package cn.itcast.day07.demo04;
    
    public class DemoMain {
        public static void main(String[] args) {
            //准备一个笔记本电脑
            Computer computer = new Computer();
            //开机
            computer.powerOn();
            //准备一个鼠标,并拿起其USB
            USB usbMouse  = new Mouse();
            //将鼠标连接上电脑
            computer.useDevice(usbMouse);
            //使用鼠标
            ((Mouse) usbMouse).click();//向下转换
            ((Mouse) usbMouse).move();//向下转换
    
            //准备一个键盘,并拿起其USB
            USB usbKeyboard = new Keyboard();
            //将键盘连接上电脑
            computer.useDevice(usbKeyboard);
            //使用键盘
            ((Keyboard) usbKeyboard).point();//向下转换
    
            //拔出鼠标和键盘
            computer.closeDevice(usbMouse);
            computer.closeDevice(usbKeyboard);
            //关机
            computer.powerOff();
    
            //
        }
    }
    出鼠标和键盘
            computer.closeDevice(usbMouse);
            computer.closeDevice(usbKeyboard);
            //关机
            computer.powerOff();
    
            //
        }
    }
    
    展开全文
  • JAVA 继承、多态

    2012-12-23 15:16:34
    1.子类实例化时会先实例化父类(调用父类构造方法...英文单词 OverLoad OverWrite 2 概念 方法名称相同,参数类型或个数不同 方法名称、参数类型或个数完全相同 3 注意点   访问权限不能变小 4

    1.子类实例化时会先实例化父类(调用父类构造方法)

    2.方法覆写 权限级别 private<default<public (private 父类定义,子类重写后都是新方法)


    方法重载与覆写区别

    NO 比较点 重载 覆写
    1 英文单词 OverLoad OverWrite
    2 概念 方法名称相同,参数类型或个数不同 方法名称、参数类型或个数完全相同
    3 注意点   访问权限不能变小
    4 范围 在同一个类中性中 在继承类中发生



    package org.poldemo;
    
    class A{
    	public void fun1(){
    		System.out.println("A类 fun1")
    	}
    	public void fun2(){
    		fun1();
    	}
    }
    class B  extends A{
    	public void fun1(){
    		System.out.println("B类fun1");
    	}
    	public void fun3(){
    		System.out.println("B类fun3");
    	}
    }
    
    public class PolDemo01 {
    
    	/**
    	 * @param args
    	 */
    	public static void main(String[] args) {
    		// TODO Auto-generated method stub
    		B b = new B();
    		b.fun2();
    		A a = new B(); //向上传型 子类实例-->父类实例
    		a.fun2();
    		B b2 = (B)a; //向下强制转型
    		b2.fun2();
    		b2.fun3();
    	}
    
    }
    

    常见异常:

    classcastexception:表示类转换异常,造成的根本原因是两个没关系的类进行相互的对象转换操作

    nullpointerexception:实例未初始化 导致空异常


    多态的应用场景:

    package org.poldemo;
    
    class A{
    	public void fun1(){
    		System.out.println("A类 fun1");
    	}
    	public void fun2(){
    		fun1();
    	}
    }
    class B  extends A{
    	public void fun1(){
    		System.out.println("B类fun1");
    	}
    	public void fun3(){
    		System.out.println("B类fun3");
    	}
    }
    
    class C  extends A{
    	public void fun1(){
    		System.out.println("C类fun1");
    	}
    	public void fun4(){
    		System.out.println("C类fun4");
    	}
    }
    
    public class PolDemo01 {
    
    	/**
    	 * @param args
    	 */
    	public static void main(String[] args) {
    		// TODO Auto-generated method stub
    		fun(new B());
    		fun(new C());
    	}
    	
    	public static void fun(A a){
    		a.fun2();
    		if (a instanceof B){
    			B b = (B)a;
    			b.fun3();
    		}
    		if (a instanceof C){
    			C c = (C)a;
    			c.fun4();
    		}
    	}
    
    }
    

    展开全文
  • Java是一种面向对象设计的高级语言,支持继承、封装和多态三大基本特征,首先我们从面向对象两大概念:类和对象(也称为实例)谈起。来看看最基本的类定义语法: /*命名规则: *类名(首字母大写,多个单词组合时每个...
    
    

    JavaSE知识总结

    1.面向对象之封装、继承、多态

    Java是一种面向对象设计的高级语言,支持继承、封装和多态三大基本特征,首先我们从面向对象两大概念:类和对象(也称为实例)谈起。来看看最基本的类定义语法:

    /*命名规则:
    *类名(首字母大写,多个单词组合时每个单词首字母大写,单词之间不加任何连接符号)
    *字段名、方法名(首字母小写,多个单词组合时第一个单词首字母小写,之后每个单词首字母大写,单词之间不加任何连接符号)
    */
    [public][final] 类名 {
        [public|protected|private 类名() {}] //构造器
        [public|protected|private][static|final] 类型 字段名 [=默认值];//字段列表
        [public|protected|private][static|final|abstract] 返回值 方法名(参数) {} //方法列表
    }
    

    在上面的基本语法中,我们发现以下几个知识点:

    1. 构造器名称为类名相同且没有任何返回值(甚至都不能返回void)
    2. 字段可以添加默认值
    3. 字段与方法都可以使用static进行修饰
    4. 类的修饰符要么为public,要么没有
    5. 方法的修饰符中final和abstract不能同时使用

    此处,我将会着重介绍前面三条,后面两条我会在后面给大家总结出来。

    首先是为什么不构造器没有任何返回值?

    java中当使用new关键字来调用构造器时是有返回值的,总是返回当前的实例对象,因此无需定义返回值类型。 当我们利用构造器来实例化对象的时候,如果没有提供构造器,系统会隐式的为我们提供一个无参构造器,如果我们自己提供了一个构造器,那么系统将不会为我们提供构造器,所以当我们自己提供一个带参构造器的时候,最好手动写上无参构造器。

    但是请注意了:虽然构造器负责创建对象,但是它不全是为了创建对象而存在的,实际上当调用构造器时,系统会为创建的对象分配内存空间并执行默认化操作,即在构造器执行之前,对象就已经产生,只是不能被访问,只能在构造器中用this来引用,当构造器执行完成之后,当前这个对象才能被外界访问。

    不能理解我在说什么?好,我给大家举一个例子来加深大家对该知识的理解。

    public class Encapsulation {
        public static void main(String[] args) {
            Person p=new Person();
            System.out.println(p.getName());
        }
    }
    
    /**Person类*/
    class  Person{
        private String name="qinling";
        private int age=23;
        public String getName() {
            return name;
        }
        public Person(){
            System.out.println("构造器中的对象"+this);
        }
    }
    

    执行后,大家会发现在person的构造器中能够给输出当前对象,说明在构造器执行之前已经存在这个对象了,new对象的时候只是将这个对象返回给使用者。

    下面给大家介绍一下类的存储关系,还是上面的例子,我们给出如下的关系图:

    从上面可以看出,

    对引用类型来说,堆内存仅仅存放的是引用类型的变量名,而堆内存中存放的是对象的实际数据,通过引用变量名来引用实际的对象,如果将该变量赋值给另一个引用变量,仅仅是将两个引用变量指向了同一个对象而已,而不会发生赋值对象数据

    我们来谈论下一个知识点,java方法的参数传递问题,这个也是一个需要注意的地方。

    public class TestPassPrimitiveArgs {
        public static void swap(int a, int b) {
            System.out.println("交换前,a = " + a + ", b = " + b);//a = 3,b = 5
            int temp = a;
            a = b;
            b = temp;
            System.out.println("交换后,a = " + a + ", b = " + b);//a = 5,b = 3
        }
        public static void main(String[] args) {
            int a = 3;
            int b = 5;    
            swap(a, b);
            System.out.println("交换结束后,a = " + a + ", b = " + b);//a = 3,b = 5
        }
    }
    

    说明什么?

    说明Java方法的参数传递方式只有一种:值传递,即将实参的副本传递给方法,参数本身不发生任何变化

    从运行结果来看,在swap()中交换之前是3和5,交换后变成5和3,而实参在main()中始终变成不变,因此在main()传递给swap()的实参只是a和b的副本,而不是a和b本身。我们以内存分布来说明执行状况,当在main()中传参给swap()时,实际上就是在main()方法栈区向swap()方法栈区传递一份a和b的副本,如下图:

    当执行swap()时,swap()方法栈区将a和b副本进行交换,交换完成后进入main()方法栈区,此时仅仅a和b的副本发生改变,其本身没有发生任何变化。接下来我们来看看引用类型的交换,前面我们说了只能通过值传递的方式来传参,可能对有些朋友来说稍显疑惑。

    class DataSwap {
        public int a;
        public int b;
    }
    public class TestPassReferenceArgs {
        public static void swap(DataSwap ds) {
            System.out.println("交换前,ds.a = " + ds.a + ", ds.b = " + ds.b);//ds.a = 3, ds.b = 5
            int temp = ds.a;
            ds.a = ds.b;
            ds.b = temp;
            System.out.println("交换后,ds.a = " + ds.a + ", ds.b = " + ds.b);//ds.a = 5, ds.b = 3
        }
        public static void main(String[] args) {
            DataSwap ds = new DataSwap();
            ds.a = 3;
            ds.b = 5;
            swap(ds);
            System.out.println("交换结束后,ds.a = " + ds.a + ", ds.b = " + ds.b);//ds.a = 5, ds.b = 3
        }
    }
    

    从运行结果来看,确实不仅在swap中交换成功,在main中仍然是交换之后的结果。让人一下觉得:从main中传递给swap似乎不是ds对象的副本了,而是ds本身,这与我们前面谈到的Java方法传参只能按值传递相违背了。

    下面我详细说明一下,直接上图说明问题:

    我们都知道,此时传递的是引用类型DataSwap,而引用类型的内存方式已经谈过了,在main()方法栈区中实际存放的是ds对象的地址,而实际的数据(a,b)是存放在堆内存中。现在将ds对象引用由main传递给swap,实际上是ds对象的地址复制一份到swap方法栈区中,此时main和swap中都已拥有ds对象的地址,且都指向在堆内存中实际存放的数据。也就是说引用类型参数数据传递方式是不折不扣的值传递方式,只不过传递的仅仅是引用变量,而不是引用变量所指向的引用类型数据。当然这里对main或swap中任何一个ds对象数据的更改都会影响到另一方,同时我们还可以验证main和swap中的ds是两个不同的引用变量,试着在swap种方法最后添加: ds=null.也就是切断swap中对ds的引用,查看一下main中ds对象的a和b是否受到影响(结果是不会)。

    接下来,我们来谈一谈可变参数的实现方法(就是在类型后面添加三个点...),看实际的例子

    public class TestVarityArgs {
        public static void readBooks(String name, String... books) {
            System.out.println(Arrays.toString(books));
            if(books.length == 0) {
                System.out.println(name + " has not a book to read");
            } else {
                String result = name + " is reading: ";
                for(String book : books) {
                    result += book + " ";
                }
                System.out.println(result);
            }
        }
        public static void main(String[] args) {
            readBooks("qinling");
            readBooks("qinling", "Java", "oracle", "J2EE");
            readBooks("qinling", new String[] { "Java", "oracle", "J2EE" });
        }
    }
    

    谈到了可变参数,似乎跟重载函数非常相似,都是同一个方法有多种调用形式,但是它们有着显著的区别。重载函数必须满足"两同一不同":同一个的重载方法名的必须相同,但是形参列表不同(返回值、修饰符不能作为重载的标准)。请注意,尽量别对包含可变参数的方法进行重载,因为这样可能会引起歧义。

    前面一直提到static这个概念,接下来我以例子来说明它的应用,可以看出static和非static字段和方法的区别所在。

    public class TestCat {
        public static void main(String[] args) {
            Cat cat = new Cat("tomcat", 15);
            cat.display();
            //static方法可通过类调用,也可通过实例调用,调用效果一致,会对该类的所有实例产生影响
            cat.AddCourse(1);//p.AddCourse(1);
            cat.display();
            //cat1.courses现在也变成3
            Cat cat1 = new Cat("HelloKitty", 14);
            cat1.display();
        }
    }
    class Cat {
        public String name;
        public int age;
        public static int courses = 2;
    
        public Cat() {}
        public Cat(String name, int age) {
            this.name = name;
            this.age = age;
        }
    
        public static void AddCourse(int count) {
            //在static方法中只能访问static字段,不能访问实例字段
            //System.out.println(name + " 's course: ");
            courses += count;
        }
    
        public void display() {
            //在实例方法中可以访问static字段
            System.out.println("Name: " + name + ", Age: " + age + ", Course: " + courses);
        }
    }
    

    那在实际开发中,怎样例区分static和非static的引用呢?

    简单的建议是:如果定义的变量是用来描述每个对象的固有信息(如每个人都有姓名、年龄),则应该使用实例变量,相反如果描述的类的固有信息(如只要是人就只能有两只眼睛),则应该使用类变量

    下面开始讲解重点知识:

    封装

    封装就是将对象的属性等信息隐藏在类的内部,仅提供给外部一些满足预设条件的方法供调用。拿上面的例子来说明:每个人的年龄只能在0~150之间来进行浮动,现在的情况是我可以随意更改年龄(想多少岁就多少岁),那肯定就不对了。我们必须将这些不满足条件的操作及时的过滤掉,Java提供了访问权限控制: private->default->protected->public(权限依次扩大)来封装内部属性和提供外部接口(对字段采用private或protected等修饰符来限制,采用getter和setter来进行有效控制)

    关于访问控制符,有以下建议:类的绝大部分字段(有些少数的static字段需要public修饰)和辅助方法都采用private来修饰,并提供getter和setter访问器来对其读取和修改;如果值希望同一个包中其他类访问,则不添加任何修饰符;如果只希望子类也能使用父类的成员而不被外界知晓,则采用protected来修饰;如果可以在任何地方都能访问到,则采用public来修饰

    继承

    继承就是在已有类的基础上扩展新的子类,而不改变原有父类的数据和行为,即我们通常所说的父类和子类(遵从"子类 is a 父类"原则),子类可继承父类的非私有成员(建议将成员修饰符改为protected),同时也可重写父类相同的成员

    遵从"两同两小一大"原则:即方法名相同,方法形参相同;子类方法返回类型比父类更小或相等,子类方法抛出的异常比父类更小或相等;子类方法的访问权限比父类更大或相等,重写的方法要么都是类方法,要么都是实例方法,如父类有一个实例方法,子类添加一个同名的类方法则不算重写,而是子类的新方法

    Father.java

    public class Father {
        private String name;
        private int age;
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public int getAge() {
            return age;
        }
        public void setAge(int age) {
            this.age = age;
        }
        public void display(){
            System.out.println("father-->display");
        }
    }
    

    Child.java

    public class Child extends Father {
        @Override
        public void display() {//重写了父类的方法
            System.out.println("child-->display");
        }
        public static void main(String[] args) {
            Child c=new Child();
            c.setAge(12);
            c.setName("child");
            System.out.println(c.getAge());
            System.out.println(c.getName());
            c.display();
        }
    }
    

    如果在子类中先调用已重写的父类方法,该怎么办呢?Java提供了super引用,指向其直接父类的默认引用。当创建一个对象时,系统会隐式创建其父类的对象(Java所有类都继承自java.lang.Object),只要该类有子类存在,就一定会产生super引用,指向其对应的直接父类,当子类方法中使用某个成员变量时,首先会查找当前类中是否存在,如不存在则查找直接父类中是否存在,如不存在会依次追溯到java.lang.Object中是否存在,如仍然不存在将不能通过编译。

    我们将上面的代码稍作调整Father c=new Child();

    运行之后我们会发现,虽然是父类对象,但是还是调用了子类的方法。

    则我们有如下的结论:

    当引用变量的编译时类型和运行时类型不一致(父类 t = new 子类();)时,我们说表现出了对象的多态。而多态仅仅表现在调用重写方法时,将调用子类中的方法,调用非重写方法时,如果该方法在父类中将调用父类,如果在子类中将无法调用,而对象的字段不具多态性,即只能调用父类中对应的字段。

    到现在为止,基本讲完了面向对象的三大特性,在结束本篇讲解之前,简单谈一下"初始化块"的应用。

    所谓初始化块,就是在构造器执行之前,对整个类(所有对象)的字段进行初始化的过程,通常会将多个构造器中相同的部分放到初始化块中执行,可以把初始化块看成是没有形参的方法,只不过在构造器执行之前执行而已。与构造器执行顺序一致,初始化块也遵循从父类到子类依次执行的过程。与初始化块对应的还有静态初始化块,主要完成类属性的初始化,并且只在类加载时初始化一次。

    Father.java

    public class Father {
        static {
            a = 4;
            System.out.println("Father的静态初始化块执行");
        }
        {
            b = 4;
    
            System.out.println("Father的初始化块执行");
        }
    
        public static int a = 2;
        public int b = 3;
    
        public Father() {
            System.out.println("Father的构造器执行");
        }
    }
    

    Child.java

    public class Child extends Father {
        static {
            // a = 10;
            System.out.println("Child的静态初始化块执行");
        }
        {
            b = 6;
            System.out.println("Child的初始化块执行");
        }
    
        public Child() {
            System.out.println("Child的构造器执行");
        }
    
        public static void main(String[] args) {
            for(int i = 0; i < 2; i++) {
                Child c = new Child();
                System.out.println("a: " + Father.a + ", b: " + c.b);
            }
        }
    }
    

    运行结果:

    Father的静态初始化块执行
    Child的静态初始化块执行
    Father的初始化块执行
    Father的构造器执行
    Child的初始化块执行
    Child的构造器执行
    a: 2, b: 6
    Father的初始化块执行
    Father的构造器执行
    Child的初始化块执行
    Child的构造器执行
    a: 2, b: 6
    

    从运行结果来看:静态初始化块和初始化块都先于构造器执行,并都遵从父类到子类的执行过程,但静态初始化块最先执行且仅执行一次,子类初始化块在父类的初始化块和构造器执行完毕之后,在子类构造器之前执行

    OK,到此为止,面向对象的三大基本特征就总结完成。希望大家能自行仔细琢磨一下其中原理.

    展开全文
  • 多态 继承、封装、多态、抽象是面向对象编程...所谓多态,英文单词为polymorphism,这个英文单词是由单词poly(意思是很多或多个)和morph(意思是形状或形式)组成的复合词。多态一词最早出现在生物学,是指生物学...
  • 设计一个数据类型判断类Polymorphism,使用重载、装箱等技术判断一个不带等号的Java表达式的结果的数据类型。 设计一个链表结点类LinkNode,此类可以存放int、long、float、double、byte、short、String、...
  • final关键字 final关键字是最终的意思,可以修饰(方法,变量,类) ...//常量的命名规范:如果是一个单词,所有字母大写,如果是多个单词,所有字母大写 //但中间需要使用_分隔 final int NAX = 10; final
  • Java是一种面向对象设计的高级语言,支持继承、封装和多态三大基本特征,首先我们从面向对象两大概念:类和对象(也称为实例)谈起。来看看最基本的类定义语法: /*命名规则: *类名(首字母大写,多个单词组合时...
  • 本篇是面向对象的又一大精华,面向对象的过程,就是在不断的抽象和总结,把关注的事物从不同的方面,根据不同的角度和需求总结出自己的看法和基本规律,笔者最近在看java设计模式之禅,刚看完组合模式就觉得那些玩...
  • final关键字 被其修饰的类,不能被继承。 被其修饰的方法,不能被覆盖。 被其修饰的变量,是一个常量,不能被修改,所以... 所有字母大写,多个单词,中间用下划线连接。 抽象类 猫和狗有共性,将共性抽取出来,放...
  • 初次见到这两个单词并没有什么特别的感觉,但是时间长了,却发现书上一会儿用override,一会儿又用overload,搞得我的迷迷糊。于是就做了个总结,希望能对和我一样对这两个概念模糊不清的网友有一个帮助。 override ...
  • final和多态

    2017-10-13 22:18:24
    2.Java规范中 final 定义的常量的单词字母都要大写。 3.构造函数私有化: 单例设计模式:只留有一个类的一个实例化对象,例如: private final static Singleton instance = new Singleton ();
  • java相关英文单词

    2018-06-09 21:47:17
    primitive:原生polymorphism:多态
  • 面向对象——多态

    2016-06-07 10:28:44
    对象的多态性多态性在面向对象是一个最重要的概念,在Java中面向对象主要有以下两种主要体现: 方法的重载和覆写 对象的多态性关于方法的重载和覆写的区别 区别点 重载 覆写 单词 Overloading Overriding 定义 ...
  • 这几天逐渐被idea所折服,越来越喜欢这个优雅又强大的代码编辑器,有很多人说idea对很多初学者不友好,但是在我看来,只要你足够自律,并且英语不会太差,语法上关键的几个单词没什么大问题,idea对初学者是有很大...
  • 1.Java是面向对象的编程语言,对象就是面向对象程序设计的核心。所谓对象就是真实世界中的实体,对象与实体的一一对应的,也就是说现实世界中每一个实体都是一个对象,他是一种具体的概念。 对象有以下特点: 对象...
  • 接口中可以定义成员变量,但是这可不是一般的成员变量,它从效果中来看。其实是接口中的常量 final是不可变的意思 static也删掉了 同样可以的 ...如果有多个单词的话用下划线分隔开...
  • Java例子

    2019-10-07 15:25:14
    多态 2. 书面作业 Q1. java HelloWorld命令中,HelloWorld这个参数是什么含义? 今天学了一个重要的命令javac 英语单词不会,请到必应词典 Q2. JDK与JRE有什么区别? 2.1 第一题的答案是。JDK是java运行时环境。JDK...
  • Java基础

    2017-08-24 21:09:22
    注:以下整理自w3cschool一、基本知识1.类名:对于所有的类来说,类名的首字母应该大写。如果类名由若干单词组成,那么每个...2. Java支持的基本概念: 多态 继承 封装 抽象 类 对象 实例 方法 消息解析 3
  • java 例子

    2017-09-13 09:08:00
    多态 2. 书面作业 Q1. java HelloWorld命令中,HelloWorld这个参数是什么含义? 今天学了一个重要的命令javac 英语单词不会,请到必应词典 Q2. JDK与JRE有什么区别? 2.1 第一题的答案是。JDK是java运行时环境。JDK...
  • Java基础概念

    2020-05-16 07:09:01
    1、Java面向对象的特征:封装、继承、多态、抽象 2、Java中有没goto、const? goto 是Java中的保留字,在目前版本的Java中没有使用。(根据James Gosling(Java之父)编写的《The Java Programming Language》一书的...
  • Java语法基础

    2019-09-24 08:58:49
    JDK = JRE + Java 的开发工具(javac.exe,java.exe,javadoc.exe) JRE = JVM + Java 核心类库 Java 语言的特点: 1.面向对象性: ...关键字:被 Java 语言赋予了特殊含义,用作专门用途的字符串(单词)。 保...
  • Java-API

    2020-10-04 19:33:40
    1.今日单词: Override:重写重写覆盖 Annotation:注解 abstract:抽象 2.方法重新:如何判断调用的是谁? 等号左边调用的是是谁就用谁。如果方法重写,那么等号右边是谁调用的就是谁有没有向下转变?有,但是不...
  • 认识Java002

    2014-11-29 18:28:00
    ——关键字:被Java赋予特殊含义的单词,关键字中所有字母都小写,如class true 标识符:程序中自定义的一些名称,包括字母,数字,下划线,$,数字不能开头 标识符命名规则:包名:所有母小写 类名接口名:所有单词...
  • 目录java语言语法基础标识符、关键字、注释与分隔符数据类型对象和类定义类封装类对象的创建与使用继承和多态重用类的继承多态抽象类、接口与嵌套类抽象类接口嵌套类object类谢谢观看 java语言语法基础 标识符、...
  • 疯狂java——day03

    2020-07-27 08:44:00
    继承 封装、继承、多态----------面向对象3大特征。...​ java的继承使用的是extends单词,扩展。 ​ 父类(超类、基类、大类);子类(派生类、小类) 继承语法 [修饰符] class 类名 extends 父类 {
  • 面向对象只是一个模式,它提供许多概念,如继承,数据绑定,多态等等。拉勾IT课小编为大家分解Simula是第一种面向对象的编程语言。而一切都可表示为对象的编程模式被称为真正的面向对象的编程语言。Smalltalk是第一...

空空如也

空空如也

1 2 3 4 5 6
收藏数 104
精华内容 41
关键字:

多态单词java

java 订阅