【动力节点】javaSE-basics

1. 环境搭建

1.1. 常用DOS命令

  • mkdr 文件名:创建目录

  • exit:退出当前DOS命令窗口

  • cls:清屏`

  • DOS窗口内容复制:选中内容+右键(win10)

  • dir:列出当前目录下所有子文件/子目录

  • cd命令:改变目录

  • 假设当前目录为:C:\Users\Administrator

    • 相对路径 :如cd Desktop
    • 绝对路径:如 cd C:\Users\Administrator\Desktop
    • cd … :回到上级目录
    • **cd \ ** :直接回到根目录
  • . 一个点 :代表当前路径。(cd命令用不着。以后配置环境变量的时候一个点有用处。)

  • 在根目录切换盘符:c(d、f) :

  • del命令:删除文件

    • 删除具体某个文件

      如: del T1class 删除T1class 文件

    • 删除符合条件的多个文件

      如:del *class 删除T1class 和T2class文件

      del *ass 删除T1class和T1glass文件

  • 查看本机IP地址

    • ipconfig:查看ip地址的配置信息
    • ipconfig /all :查看更详细的网络信息
      这个详细信息中包括网卡 的物理地址,例如:70-8B-CD-A7-BA-25
      这个物理地址具有全球唯一性。物理地址通常叫做MAC地址。
  • ping命令:查看两台计算机是否可以正常通信

    语法格式:
    ping IP地址
    ping 域名

    如:ping www.baidu.com
    ping 61.135.169.121 (61.135.169.121是百度的IP地址)
    ping 61.135.169.121 -t (-t参数表示一直ping,一直ping的目的可以查看网络是否稳定。)

  • ctrl+c:强行终止dos命令

1.2. 常用文本编辑快捷键

    • 复制 ctrl + c
    • 粘贴 ctrl + v
    • 剪切 ctrl + x
    • 保存 ctrl + s
    • 撤销 ctrl + z
    • 重做 ctrl + y
    • 回到行首:home键
    • 回到行尾:end键
    • 当光标在行尾,选中一行:shift + home键
    • 当光标在行首,选中一行:shift + end键
    • 回到文件头:ctrl + home
    • 回到文件尾:ctrl + end
  • 全选:ctrl + a

  • 查找:ctrl + f

    • 选中一个单词:鼠标双击
    • 选中一行:鼠标连续击3次

1.3. 环境变量配置

  • 环境变量包括“系统变量”和“用户变量”

    • 系统变量:范围比较大,系统变量会让计算机所有用户都起作用。
    • 用户变量:范围比较小,这个变量只是作用于当前用户。
  • JAVA_HOME :JDK文件夹位置

    CLASSPATH : .;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar;

    Path :

    • %JAVA_HOME%\bin
    • %JAVA_HOME%\jre\bin
  • JDK中没有jre文件的处理方法

    管理员身份运行cmd–>cd至JDK文件夹–>输入bin\jlink.exe --module-path jmods --add-modules java.desktop --output jre,回车

  • javac命令:编译“.java"文件(源代码),生成".class"文件(字节码)

    • 格式:javac java源文件的路径

    java命令:运行”.class“文件

    • 格式1:在class文件目录下,java 类名

      注意:java命令,后面跟的是“类名”,而绝对不能跟“文件路径”

      如:运行Helloworld.class文件,在该文件的目录下 java HelloWorld

    • 格式2:在高版本的JDK当中,可以:java x/y/z/xxx.java
      java后面直接加java源文件的路径。这个特性是为了简化开发而提出,但实际上底层的实现原理还是和以前一样的,还是会先进行编译,然后再运行。并且以上的运行方式,
      编译生成的class文件在硬盘上不存在,看不到。

1.4. 注释

  • // 单行注释
    
  • 	/*
     	多行注释
    	 	*/
    
  • /**
    
    *javadoc注释:这里的注释信息可以自动被javadoc.exe命令解析提取并生成到帮助文档当中。
    */
    

1.5. 类体的概念

  • 类名后面必须是一对大括号,这对大括号里的内容称为类体

  • 在Java中任何有效代码必须写到类体中,最外层必须是一个类的定义。

  • 方法必须放在类体中。且类体中应该是方法,而不是Java语句。

  • 如果类体中没有main方法可以编译成功,但无法运行。

  • public class 和 class 的区别

    • 一个Java源文件中可以定义多个类。
    • 在源文件中如果有n个class的定义,则必然会生成对应n个class文件。
    • public 类不是必须的。但如果有,public修饰的类名必须和源文件名保持一致。
    • public类有且只能有一个

2. 基础语法

2.1. 标识符

2.1.1. 含义
  • 程序员有权利命名的单词都是标识符。
  • 标识符可以标识类名、方法名、变量名、接口名、常量名······
  • main是标识符,但是不能更改。
2.1.2. 命名规则
  • 标识符只能由数字、字母(包括中文)、下划线、美元符号组成,不能含有其他符号。
  • 标识符不能以数字开头。
  • 关键字不能做标识符。
  • 标识符严格区分大小写。但是对于类名来说,如果一个Java源文件同时出现了A类和a类,那么谁在前就生成谁。
  • 标识符理论上没有长度限制。
2.1.3. 命名规范
  • 见名知意
  • 遵循驼峰命名方式(单词与单词之间很好地进行分隔)如 RightTest
  • 类名和接口名首字母大写,后面每个单词首字母大写。如StudentTest,UseTest
  • 变量名和方法名首字母小写,后面每个单词首字母小写。如studentTest, useTest
  • 所有常量名全部大写,且单词和单词之间采用下划线衔接。如USER_AGE

2.2. 关键字

  • 关键字都是小写

2.3. 变量

2.3.1. 字面量

字面量就是数据,包括整形、浮点型、字符型(’ ')、字符串型(" ")、布尔型。

2.3.2. 变量的含义
  • 变量是内存中存储数据的最基本的单元。
  • 不同的数据类型在内存中分配的空间大小不同。
    • 一个字节=8个bit(二进制位)
    • 一个int占用4个字节,32个bit
2.3.3. 变量的使用
  • 变量的三要素:数据类型、变量名、值

  • 变量必须先声明,再赋值(手动赋值)才能访问

  • 一行上可以同时声明多个变量

    • int a, b, c = 100;(a、b没有赋值,c赋值100
    • int a = 10, b = 20, c = 100;(a、b、c都赋值)
      
2.3.4. 变量的分类
  • 局部变量:在方法体内声明的变量

    成员变量:在方法体之外,类体内声明的变量

  • 局部变量只在方法体内有效,方法体执行结束该变量的内存就释放了。

  • 就近原则:当局部变量和成员变量重名时。哪个近就访问哪个。

  • for循环中声明的变量【如for(int n=0;n<10;n++)】,在for循环结束后就不能访问了。
    

2.4. 数据类型

2.4.1. 作用

数据类型用来声明变量,程序在运行过程中根据不同的数据类型分配不同大小的空间。

2.4.2. 种类
  • 基本数据类型

    • 整数型:byte,short,int,long
    • 浮点型:float,double
    • 布尔型:boolean
    • 字符型:char
  • 引用数据类型

    字符串型String属于引用数据类型。

2.4.3. 区别

占用的空间大小不同

1 byte(字节) = 8 bit

1 KB = 1024 byte

类型占用字节数量
byte1
short2
int4
long8
float4
double8
boolean1 (00000001为true,00000000为false)
char2
2.4.4. 取值范围

byte(一个字节) 的范围[-128,127],可以标识256个不同数字。

short(两个字节)的范围[-32768, 32767]

int(四个字节)的范围[-2147483648, 2147483647]

char(两个字节)的范围[0, 65535]

short和char实际上容量相同,不过char可以表示更大的数字。因为char表示的是文字,没有正负之分。

注意

  • 整形字面量默认会当作int类型处理。如果定义变量的值超出int范围,要在值后面加“L”

​ 如: long i = 2147483648L

  • 浮点型字面量默认会当作double类型处理。如果想让字面量当作float类型处理,要在字面量后加“F/f”

    如 1.0f

2.4.5. 类型转换规则
  • 八种基本数据类型中,除 boolean 类型不能转换,剩下七种类型之间都可以进行转换。
  • 如果整数型字面量没有超出 byte,short,char 的取值范围,可以直接将其赋值给byte,short,char 类型的变量。
  • 小容量向大容量转换称为自动类型转换,容量从小到大的排序为:byte < short(char) < int < long < float < double,其中 short和 char 都占用两个字节,但是char 可以表示更大的正整数。
  • 大容量转换成小容量,称为强制类型转换,编写时必须添加“强制类型转换符”,但运行时可能出现精度损失,谨慎使用。
  • byte,short,char 类型混合运算时,先各自转换成 int 类型再做运算
  • 多种数据类型混合运算,各自先转换成容量最大的那一种再做运算。

2.5. 运算符

算术运算符:

​ + - * / %(取余) ++ –

i++(–)表示先做赋值运算,再自加一

++(–)i表示先自加一,再做赋值运算

关系运算符:
> >= < <= == !=

逻辑运算符
&(逻辑与) |(逻辑或) !(逻辑非) &&(短语与) ||(短路或)

&&:左边表达式若为false,则右边表达式不再执行。

​ 如: x = 10; y = 11 ;

​ x>y & x>y++ // y = 11

​ x>y && x>y++ // y = 12

||:左边表达式若为true,则右边表达式不再执行。

​ 如: x = 10; y = 11 ;

​ x<y | x>y++ // y = 11

​ x<y || x>y++ // y = 12

赋值运算符
基本赋值运算符:=

​ 扩展运算符:+= -= *= /= %=

三目运算符
布尔表达式 ? 表达式1 : 表达式2

字符串拼接运算符

​ + (任意一边是字符串类型,就会进行拼接操作

易错注意

  • int  i  =   10;
    
    i  =   i++     //  c++ 中 i为 11;Java中i为10。Java将 i 临时保存(temp=i;  i++;  i=temp)
    
  • int i  = 10System.out.println(i++)     //   输出为10,i = 11
    

2.6. 控制语句

2.6.1. 选择语句(分支语句)
  • if 语句

    ​ 从上往下依次判断,第一个true对应的分支执行。只要有一个分支执行,整个if结束。

  • switch 语句

    • switch的值只支持int和String类型

    • 如果分支执行了,但分支里没有break,会发生case穿透现象,即直接执行下面case分支中的语句,直到遇到break。

    • 如果所有case都不匹配,执行default中的语句。

2.6.2. 循环语句
  • for 循环
  • while 循环
  • do…while 循环
2.6.3. 转向语句
  • break;
  • continue;
  • return;

2.7. 方法

2.7.1. 方法的定义
[修饰符列表] 返回值类型 方法名(形式参数列表){

	方法体;
}
  • 修饰符列表:可选项。如:public static
  • 返回值类型:包括基本数据类型和引用数据类型

方法调用:类名.方法名(实际参数)

2.7.2. 方法的重载
  • 满足方法重载的条件

    • 在同一个类中
    • 方法名相同
    • 参数列表不同(可以是个数、顺序、类型
  • 方法重载和方法的返回值类型修饰符列表无关。

2.7.3. 方法的递归

3. 面向对象

3.1. 认识面向对象

3.1.1. 面向过程和面向对象
  • 语言方面

    • 对于C语言来说,是完全面向过程的。
    • 对于C++语言来说,是一半面向过程,一半是面向对象。(C++是半面向对象的)。
    • 对于Java语言来说,是完全面向对象的。
  • 面向过程

    • 特点

      注重步骤,注重的是实现这个功能的步骤。
      第一步干什么
      第二步干什么

      另外面向过程也注重实现功能的因果关系。
      因为A所有B
      因为B所以C
      因为C所以D

      面向过程中没有对象的概念。只是实现这个功能的步骤以及因果关系。

    • 缺点:耦合度高,扩展力差。

      面向过程最主要是每一步与每一步的因果关系,其中A步骤因果关系到B步骤,A和B联合起来形成一个子模块,子模块和子模块之间又因为因果关系结合在一起,假设其中任何一个因果关系出现问题(错误),此时整个系统的运转都会出现问题。(代码和代码之间的耦合度太高,扩展力太差。)

    • 优点:快速开发
      对于小型项目(功能),采用面向过程的方式进行开发,效率较高。不需要前期进行对象的提取,模型的建立,采用面向过程方式可以直接开始干活。一上来直接写代码,编写因果关系。从而实现功能。

  • 面向对象

    • 特点

      面向对象就是将现实世界分割成不同的单元,然后每一个单元都实现成对象,然后给一个环境驱动一下,让各个对象之间协作起来形成一个系统。

      对象“张三”
      	对象“香烟”
      	对象“打火机”
      	对象“吸烟的场所”
      	然后将以上的4个对象组合在一起,就可以模拟一个人的抽烟场景。
      	其中“张三”对象可以更换为“李四”
      	其中“香烟”也可以更换品牌。
      	其中“打火机”也可以更换。
      	其中“吸烟的场所”也可以更换。
      
    • 优点:耦合度低,扩展力强。

  • 面向过程主要关注的是:实现步骤以及整个过程。
    面向对象主要关注的是:对象A,对象B,对象C,然后对象ABC组合,或者CBA组合…

3.1.2. 相关术语
  • OOA:面向对象分析

    OOD:面向对象设计

    OOP:面向对象编程

  • 实现一个软件的过程:
    分析(A) --> 设计(D) --> 编程§

3.1.3. 特征
  • 封装
  • 继承
  • 多态
3.1.4. 类和对象的概念
  • 类实际上在现实世界当中是不存在的,是一个抽象的概念。类本质上是现实世界当中某些事物具有共同特征,将这些共同特征提取出来形成的概念就是个“类”,“类”就是一个模板。

    语法格式:

    [修饰符列表] class 类名(类名属于基本数据类型) {
    			//类体 = 属性 + 方法
    			// 属性在代码上以“变量”的形式存在(描述状态)
    			// 方法描述动作/行为
    		}
    

    注意:修饰符列表可以省略。

  • 对象

    对象是实际存在的个体。(真实存在的个体)

    创建对象的语法:类名 变量名(也叫引用) = new 类名();

  • 举例

    ​ 宋小宝就是一个对象
    ​ 姚明就是一个对象
    ​ 刘德华就是一个对象
    ​ …

    ​ 宋小宝、姚明、刘德华这3个对象都属于“明星”这个类。

在java语言中,要想得到“对象”,必须先定义“类”,“对象”是通过“类”这个模板创造出来的。
	类就是一个模板:类中描述的是所有对象的“共同特征信息”
	对象就是通过类创建出的个体。
	
	这几个术语你需要自己能够阐述出来:
		类:不存在的,人类大脑思考总结一个模板(这个模板当中描述了共同特征。)
		对象:实际存在的个体。
		实例:对象还有另一个名字叫做实例。
		实例化:通过类这个模板创建对象的过程,叫做:实例化。
		抽象:多个对象具有共同特征,进行思考总结抽取共同特征的过程。

		类 --【实例化】--> 对象(实例)
		对象 --【抽象】--> 类
	
	类是一个模板,是描述共同特征的一个模板,那么共同特征包括什么呢?

		潘长江对象:
			名字:潘长江
			身高:165cm
			打篮球:非专业的,自己玩儿呢,无所谓了
			学习:考试80分

		姚明对象:
			名字:姚明
			身高:240cm
			打篮球:NBA专业球员,打篮球非常棒
			学习:考试100分

		共同特征包括哪些?
			名字、身高都属于名词(状态特征)
			打篮球、学习都属于动词(动作特征)
		
		类 = 属性 + 方法
		属性来源于:状态
		方法来源于:动作

		public class 明星类{
			//属性-->状态,多见于名词
			名字属性;
			身高属性;

			//方法-->动作,多见于动词
			打篮球方法(){}
			学习方法(){}
		}

		有共同特征,就可以抽象一个类模板出来。
		可以定义一个学生类(Studentpublic class Student {
			// 属性
			// 姓名
			// 性别
			// 身高

			// 方法
			public .... sing(){}
			public .... dance(){}
			public .... study(){}
			....
		}

007-类和对象的理解

3.2. 对象的创建和使用

3.2.1. 对象的创建和使用

009-对象和引用

  • 什么是实例变量?
    对象又被称为实例。
    实例变量实际上就是:对象级别的变量。

    public class 明星类{
    		double height;
    }
    

    ​ 身高这个属性所有的明星对象都有,但是每一个对象都有“自己的身高值”。
    ​ 假设创建10个明星对象,height变量应该有10份。
    ​ 所以这种变量被称为对象级别的变量。属于实例变量。

  • 对象和引用的区别?
    对象是通过new出来的,在堆内存中存储。
    引用是:但凡是变量,并且该变量中保存了内存地址指向了堆内存当中的对象的。

实例变量只能通过引用来访问,不能通过类名访问。

访问实例变量:引用.实例变量

如:S2.name

3.2.2. 空指针异常(NullPointerException)

“空引用”访问实例(对象)相关的数据时,都会出现空指针异常。

010-空指针异常是怎么发生的

3.2.3. 构造方法
  • 当一个类中没有提供任何构造方法,系统默认提供一个无参数的构造方法。

    这个无参数的构造方法叫做缺省构造器

  • 当一个类中手动的提供了构造方法,那么系统将不再默认提供无参数构造方法。

建议将无参数构造方法手动的写出来,这样一定不会出问题。

  • 无参数构造方法和有参数的构造方法都可以调用

    调用语法:new 方法名(实际参数列表)

    Student x = new Student();
    Student y = new Student(123);
    
  • 构造方法的语法结构

    [修饰符列表] 构造方法名(形式参数列表){
        
    	构造方法体;(通常在构造方法体中给属性赋值,完成属性初始化。)
    }
    
    • 修饰符列表统一写 public
    • 构造方法名和类名必须一致
    • 构造方法不需要指定返回值类型,也不能写void。
  • 构造方法支持方法重载。

3.3. 封装

3.3.1. 作用
  • 保证内部结构的安全
  • 屏蔽复杂,暴露简单
3.3.2. 代码实现
  • 第一步属性私有化(使用private关键字进行修饰。)

    【private修饰的数据表示私有的,私有的数据只能在本类当中访问

  • 第二步:对外提供简单的操作入口。

    1个属性对外提供set和get方法。外部程序只能通过set方法修改,只能通过get方法读取,可以在set方法中设立关卡来保证数据的安全性。

    注意

    • set和get方法都是实例方法,不能带static。

    • 语法规则

      public void set+属性名首字母大写(1个参数){
      	xxx = 1个参数;
      }	
      
      public 返回值类型 get+属性名首字母大写(无参){
      	return xxx;
      }
      
3.3.3. 实例方法
  • static修饰的统一都是静态的,都是类相关的,不需要new对象。

    • 带有static的方法如何调用? 类名.方法

    • 不带static的方法称为实例方法(对象方法,对象级别的方法)。

      如何调用

      第一步:创建对象

      第二步:通过“引用.方法”的方式访问实例方法。

  • 实例相关的必须现有对象才能访问,可能会出现空指针异常。

    静态相关的不需要对象的参与即可访问,没有空指针异常的发生。

3.4. this和static

3.4.1. static
  • 所有static关键字修饰的都是类相关的,类级别的。

    所有static修饰的变量和方法,都是采用“类名.”的方式访问。

  • static修饰的变量称为:静态变量

    static修饰的方法称为:静态方法

  • 静态变量在类加载时初始化,不需要new对象,静态变量的空间就开出来了。

    静态变量储存在方法区。

  • 什么时候变量声明为静态?

    如果这个类型的所有对象的某个属性值都是一样的,定义实例变量会浪费空间,建议定义为静态变量,在方法区中只保留一份,节省内存。

    • 变量country为实例变量时内存图:016-变量什么时候声明为静态变量

    • 变量country为静态变量时内存图:

      017-变量什么时候声明为静态的2

    • 内存中各区域的作用和存放内容

      • 栈:方法只要执行,会压栈。 (局部变量)
      • 堆:new出来对象都在堆中。 垃圾回收器(GC)主要针对。(实例变量)
      • 方法区:类的信息、字节码信息、方法片段。(静态变量)
  • 什么时候方法声明为静态?

    • 当一个方法体中,直接访问了实例变量,这个方法一定是实例方法
    • 工具类的方法一般是静态方法
  • 静态代码块

    • 语法格式

      static {
      	方法体;
      }
      
    • 静态代码块在类加载时执行,并且在main方法之前执行。

    • 静态代码块和静态变量按自上而下顺序执行,并且只执行一次

    • 用途:一般用于在某个类加载到JVM的时刻 进行操作。

  • 实例代码块

    • 语法格式

      {
      	方法体;
      }
      
    • 只要是构造方法执行,必然在构造方法执行之前,自动执行实例语句块中的代码。

3.4.2. this
  • this的内存:

    015-this关键字

    this是一个变量,是一个引用。this储存在堆内存中对象内部,保存当前对象的内存地址,指向自身。

  • this可以使用在实例方法中(静态方法的调用不需要对象),谁调用了方法,this就代表谁,所以this代表当前对象。

  • this可以使用在构造方法中,可以通过当前构造方法去调用另一个本类的构造方法。

    语法:

    this(实际参数列表);
    

    this()的调用只能出现在构造方法的第一行。

    例:

    class Date(){
        private int year;
        private int month;
        private int day;
        
        public Date(int year, int month, int day){
            this.year = year;
            this.month = month;
            this.day = day;
        }
        
        public Date(){
            this(1970,1,1); //无参构造方法默认值为1970年1月1日
        }
    }
    
  • this什么时候不能省略?

    在实例方法(或构造方法)中,为了区分局部变量和实例变量。

3.5. 继承(Extends)

3.5.1. 相关特性
  • B类继承A类,则称A类为超类(superclass)、父类、基类,B类则称为子类(subclass)、派生类、扩展类。

    class A{}
    class B extends A{}
    
  • java 中的继承只支持单继承,不支持多继承,C++中支持多继承。

    虽然 java 中不支持多继承,但有的时候会产生间接继承的效果。
    例如:class C extends B,class B extends A,

    也就是说,C 直接继承 B,其实 C 还间接继承 A。

  • java 中规定,子类继承父类,除构造方法不能继承之外,剩下都可以继承。
    但是**私有的属性无法在子类中直接访问。(**父类中private修饰的不能在子类中直接访问。可以通过间接的手段来访问。)

  • java 中的类没有显示的继承任何类,则默认继承 Object类,Object类是 java 语言提供的根类(老祖宗类),也就是说,一个对象与生俱来就有 Object类型中所有的特征。

  • 继承也存在一些缺点,例如:CreditAccount 类继承 Account 类会导致它们之间的耦合度非常高,Account 类发生改变之后会马上影响到 CreditAccount 类。

3.6. 方法覆盖(Override)

3.6.1. 条件
  • 两个类为继承关系

  • 重写之后的方法和之前继承的方法具有相同的返回值类型、方法名、形式参数列表。

  • 访问权限不能更低,可以更高。

    例:

    class A{
    	public void m(){}
    }
    class B extends A{
    	// 不能低于public,如private,protect
    	public void m(){}
    }
    
  • 重写之后的方法不能比之前的方法抛出更多的异常,可以更少。

3.6.2. 注意事项
  • 方法覆盖只针对方法,和属性无关
  • 私有方法无法覆盖
  • 构造方法不能被继承,所以也不能被覆盖
  • 方法覆盖只针对实例方法,静态方法覆盖没有意义
3.6.3. 方法覆盖与方法重载的区别
  • 方法重载发生在同一个类当中

    方法覆盖发生在具有继承关系的父子类之间

  • 方法重载是一个类中,方法名相同,参数列表不同

    方法覆盖是具有继承关系的父子类,并且重写之后的方法必须和之前的方法一致(方法名一致、参数列表一致、返回值类型一致)

3.6.4. 返回值类型
  • 对于返回值类型是基本数据类型来说,必须一致。
  • 对于返回值类型是引用数据类型来说,重写之后返回值类型可以变的更小(但意义不大,实际开发中没人这样写。)。

3.7. 多态

3.7.1. 基础语法
  • 向上转型 (自动类型转换):子–>父

    向下转型 (强制类型转换,需要加强制类型转换符):父–>子

    019-向上和向下转型

  • 什么是多态?

    多态指父类型的引用指向子类型对象。

    包括编译阶段和运行阶段,编译阶段绑定父类型的方法;运行阶段绑定子类型对象的方法。

  • 什么时候必须进行向下转型?

    当需要访问的是子类对象中特有的方法,必须向下转型才能访问

  • 向下转型的风险:容易出现ClassCastException(类型转换异常)

    避免风险:向下转型之前要使用instanceof运算符进行判断。

    instanceof运算符,可以在程序运行阶段动态地判断某个引用指向的对象是否为某一种类型。

    好习惯】向下转型时都用instanceof运算符进行判断。

public class Animal{
    public void say(){
        System.out.println("`````");
    }
}
public class Cat extends Animal{
     public void say(){
         System.out.println("miao");
     }
	 public void catchMouse(){}
}
public class Bird extends Animal{
    public void fly(){}
}
Animal s1 = new Cat(); //向上转型
s1.say(); //输出"miao"
Cat s2 = (Cat)s1; //向下转型

s1.catchMouse(); //×,不能访问
s2.catchMouse(); //√,可以访问

Animal s3 = new Bird(); 
Cat s4 = (Cat)s3;
s4.catchMouse(); //×,不能访问,编译没有问题,但在运行时会出现ClassCastException(类型转换异常)错误
(s3 instanceof Cat); //结果为false,表明s4指向的堆内存中的Java对象不是Cat
(s3 instanceof Bird); //结果为true,表明s4指向的堆内存中的Java对象是Bird
Bird s5 = (Bird)s3;
s5.fly(); //√,可以访问
3.7.2. 多态在开发中的作用
  • 降低程序的耦合度,提高程序的扩展力。

    public class Master{
        public void feed(Dog d){}
        public void feed(Cat c){}
    }
    

    以上代码表示:Master和Dog以及Cat的关系很紧密(耦合度很高)。导致扩展力很低。

    public class Master{
    	public void feed(Pet p){}
    }
    

    以上代码表示:Master和Dog以及Cat的关系就脱离了,Master 关注的是Pet。

    这样Master和Dog以及Cat的耦合度就降低了,提高了软件的扩展力。

  • 软件开发原则的基本原则:OCP(对扩展开放。对修改关闭)

    面向对象编程,不建议面向具体编程。

3.8. super关键字

3.8.1. 使用
super() //表示通过子类的构造方法调用父类的构造方法
super.属性名 //访问父类的属性
super.方法名(实参) //f
3.8.2. super和this的比较
  • this:

    • 能出现在实例方法和构造方法中

    • 语法是"this."、“this()”

    • 不能使用在静态方法中

    • 大部分情况可以省略(在区分局部变量和实例变量时不能省略

    • this()只能出现在构造方法的第一行,通过当前的构造方法去调用“本类”中其他的构造方法,

      目的是:代码复用。

  • super

    • 能出现在实例方法和构造方法中

    • 语法是"super."、“super()”

    • 不能使用在静态方法中

    • 大部分情况可以省略(如果父类和子类中有同名属性,通过子类访问父类的属性时不能省略

    • super()只能出现在构造方法的第一行,通过子类的构造方法去调用父类的的构造方法

      目的是:创建子类对象的时候,先初始化父类类型特征。

    • **super(实参)的作用:初始化当前对象的父类型特征。**并不是创建新对象,实际上对象只创建了一个。

3.8.3. 内存图

020-super关键字的理解

021-super的原理

022-SuperTest04

023-SuperTest05

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值