Java入门

一、java介绍

java是一个面向对象的编程语言,底层语言是C++,JVM是用C++写好的虚拟电脑

JDK是开发工具箱,其中有java最核心的库

java语言特性

java语言中真正操作内存的是:JVM(java虚拟机)

java屏蔽了指针概念,程序员不能直接操作内存

  • 优点:简单,不容易导致内存泄漏,因为Java有一种机制:自动垃圾回收机制(GC机制)JVM负责调度GC机制。程序员无需干涉
  • 缺点:效率问题,没c,c++效率高

计算机最主要的部件

  • CPU:中央处理器,相当于人类的大脑
  • 内存 :程序运行过程中临时数据存储空间,断电或关机之后内存中的数据消失
  • 硬盘:持久化设备,硬盘上的数据不会因断电而丢失
  • 主板:相当于人类的躯干,是一个载体,CPU、内存条、硬盘等主要部件都是放在主板上,主板上有很多线,将以上部件连接起来

java完全支持多线程并发,具有可移植性/跨平台,同样的java程序可以在windows上运行,也能在Linux上还能在MacOS运行

JDK(java软件开发工具包)包括JRE,JRE(java运行环境)包括JVM(java虚拟机)

java程序不能直接运行,需经过编译,生成“字节码”,这个“字节码”可以跨平台运行。java源代码删除后只留下字节码仍可以运行。

源代码扩展名:xxx.java 字节码扩展名为:xxx.class

java虚拟机负责把字节码翻译成二进制的代码

  1. 在硬盘上某个位置,新建.java文件
  2. 使用某个文本编辑器打开
  3. 在文件中编写符合java语法规则的源代码
  4. 保存
  5. 使用Javac(JDK安装后自带)对java文件进行编译
  6. 符合语法规则的源代码通过生成字节码

-----运行期(JRE在起作用)----

7.如果在linux上运行,需要将windows上生成的class文件拷贝过去,无需源代码,真正运行的是字节码

8.使用JDK自带的一个命令/工具:java执行字节码

9.接下来交给JVM,JVM会将字节码装载进去,然后对字节码进行解释(解释器将字节码翻译成100101…)

10.JVM将生成的二进制码交给OS操作系统,操作系统会执行二进制码和硬件进行交互

开发Java程序

写完helloword.java

需要使用到的命令:D:\program\Java\jdk-17\bin\javac.exe

环境变量包括系统变量和用户变量,系统变量范围更大

javac命令怎么用

javac java源文件的路径
在这里插入图片描述

在当前文件路径下直接打cmd 能进入DOS命令窗口,该窗口起点即为该目录,🎃快速定位技巧。

java 后跟类名无需后缀 决不能跟路径,例: java HelloWord

Javac进行编译,java执行

运行java程序步骤
  1. 先cd切换到xxx.class文件所在路径
  2. 然后java xxx

D:\code_road_java\java_development\code>java HelloWord敲回车后发生了什么

  1. 启动JVM
  2. JVM启动后,JVM启动“类加载器classloader”,类加载器会去硬盘上搜索:HellowWord.class
  3. 类加载器找不到字节码文件,错误:找不到或无法加载主类;如果找到对应的字节码文件,类加载器会将该字节码装载到JVM,JVM启动“解释器”将字节码解释为“1011010…"这种二进制,之后操作系统执行二进制码与硬件交互(默认情况下classloader从当前路径下加载文件)

如何让类加载器去指定路径下加载字节码文件?可通过设置classpath,该环境变量不属于windows操作系统,该环境变量隶属于java

👺计算机->右键-》属性-》高级系统设置-》环境变量-》新建

高版本java 可以不用编译,直接使用java 后跟绝对路径.HelloWord.java


java中的注释不会出现在字节码中

// 属于单行注释

/* */属于多行注释

类里面的东西叫做类体,public static void main(String[] args){中跟方法体}

对于主方法而言,只有args可以修改。

一个java源文件可以定义多个class,编译结果可以生成多个class。public的类不是必须的。如何有public class ,public修饰 的类名必须和源文件名保持一致。public的类有也只能有一个。

二、标识符和关键字

在editplus工具中显示的高亮颜色为黑色时,这个单词属于标识符

标识符可以标识类名、方法名、变量名、接口名、常量名…

凡是程序员自己有权命名的单词都是标识符

  1. 关键字不能做标识符
  2. 标识符不能以数字开头
  3. 标识符只能由数字、字幕、下划线、美元符号组成
  4. 对于类名来说,不区分大小写,Hello和hello一样,谁在前面生成谁

具体的命名规范

  1. 见名知意
  2. 遵循驼峰命名方式,一高一低
  3. 类名和接口名首字母大写,后面每个单词首字母大写
  4. 变量名和方法名首字母小写。后面每个单词首字母大写
  5. 所有常量名全部大写,单词间采用下划线进行衔接

在EditPlus中以蓝色字体形式存在的都是关键字 关键字例:public、int、long、float…

注意字符型用单引号,字符串型用双引号 如若使用不当会出现编译错误

javadoc可以提取注释生成帮助文档


三、变量

数据类型的作用?

根据不同的数据类型,在内存中分配不同大小的空间

方法体内容自下而上的顺序依次逐行运行

同一个域中变量名不能重名

一行可以同时声明多个变量 int a,b,c = 100;注意a,b这里没有值,但是编译能通过

方法体中声明的变量:局部变量(只在方法体内有效,方法结束,内存空间释放)

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

java中有一重要原则:就近原则

for(int n=0;n<10;n++) 这里n只属于for域,出了大括号就不认识

四、数据类型

基本数据类型可以划分为4大类8小种:

  1. 整数型 byte,short,int,long (没有小数) 1字节,2字节,4字节,8字节
  2. 浮点型 float.,double (带有小数)4字节,8字节
  3. 布尔型 boolean 1字节
  4. 字符型 char 2字节

1字节=8bit

1比特就是一个1或0

1kb=1024byte,1MB=1024KB,1GB=1024MB,1TB=1024GB

byte b=2;在计算机中表示形式:00000010

short s=2;在计算机中表示形式:00000000 00000010

int i=2;;在计算机中表示形式:00000000 00000000 00000000 00000010

十进制213转化成二进制,方法:一直除以2,余数逆序输出

二进制转十进制:例
10111 , 2 0 ∗ 1 + 2 1 ∗ 1 + 2 2 ∗ 1 + 2 3 ∗ 0 + 2 4 ∗ 1 = 23 10111,2^0*1+2^1*1+2^2*1+2^3*0+2^4*1=23 10111,201+211+221+230+241=23
byte:[-128~127]

short:[-32768,32767]

int:[-21474983648~21474983647]

char[0~65535]

字符编码是针对char类型计算机表示问题而诞生的

字符编码是人为定义的一套转换表

本质上就是一本字典,该字段描述了文字与二进制之间的对照关系。字符编码是人为规定的。

英文对应的字符编码方式是:ASCII码

ASCII码采用1byte进行储存,英文字母是26个,1byte可以表示256种不同的情况

‘a’—>97 采用ASCII进行编码 ->01100001 ->解码 后–>‘a’

‘A’—>65 …

‘0’ —>48 …

随着计算机语言的发展,后来国际标准组织制定了ISO-8859-1编码方式,又称为latin-1,向上兼容ASCII码,但不支持中文

中文编码方式:GB2312<GBK<GB18030

繁体中文 :big5

java 为了支持全球所有文字,采用unicode编码,具体实现包括:UTF-8 UTF-16 UTF-32

char 只能储存一个字

转义字符

\t 表示制表符tab

System.out.println()与System.out.print()区别,一个换行一个不换行

\' 表示一个普通的'单引号  \\表示一个普通的\字符

char x = ‘\u4e2d’ \u后面是一个字符的unicode编码,unicode编码是十六进制。

类型转换

在任何情况下,整数型的“字面量/数据”默认被当做int类型处理

long e = 2147483648;
编译会报错,因为整数会被默认为int,该数字超出int的范围,这段代码会将int转化为long,在没转换之前已经超出范围,解决办法:
long e=2147483648L;

long x =100L;

int y=x;

编译会报错,大容量不能直接赋值给小容量。小容量可以直接赋值给大容量。

long x =100L;

**int y =(int)x;**可进行强制转换,运行时可能损失精度(long强行转int会将前面的4个字节砍掉)

例如long类型,八个字节 共64个byte 0000000 00000000 ...00000000 00000010
int类型,4个字节,共32个byte

byte z=127;可以通过编译,整数型字面量可以直接赋值给byte类型的变量,只要不超出byte的范围

short z=32767;这个同上

当一个整数赋值给char类型变量的时候,会自动转换成char字符型,最终结果是一个字符

long a-10L;
char c='a';
short s=100;
int i=30;
int x= a+c+s+i ;会编译报错,因后面的累加起来是long类型,正确的方法加个强制类型转换
int (int)x= a+c+s+i ;

char+short+byte 这个除外,多种数据类型做混合运算的时候,最终结果类型是“最大容量”对应的类型。

任何一个浮点型数据默认被当做double来处理,若想让这个浮点型字面量当做float来处理,需在字面量后面添加F或者f

int i = 10.0/5;会将5先转化为double然后进行运算

在这里插入图片描述
笔试题的所有范围,在以上六条规则中。

五、运算符

++ 变量自加1

– 变量自减1

i++;

i++;皆可

int m =10;

int n = m++;运行结束后, 这里n为10,m为11

System.out.println(c++);
可以转换
int temp = c++;
System.out.println(temp);
逻辑运算符
& 逻辑与   并且
| 逻辑或   或者
! 逻辑非  取反
&& 短路与
int  x=10;
int y=11;
System.out.println(x>y && x>y++);
这里用短路与,若左边为false,右边不执行,故y=11.
若用&逻辑与,右边会继续执行,y=12。故大部分情况,使用短路与&&
|| 短路或
赋值运算符

使用扩展赋值运算符,永远不会改变运算结果类型

+= | -= | *= | /= | %= |

byte x=100;

x =x +1;编译会出错

x += 1;编译成功 等同于x = (byte)(x+1)

条件运算符

语法格式:布尔表达式 ?表达式1:表达式2

当布尔表达式为True,表达式1的执行结果作为真个表达式的结果

boolean sex=False;

char c = sex ? ‘男’ :‘女’; 返回结果 ‘女’

System.out.println(这里面什么类型的数据都能放)

字符串连接运算符

作用1:求和

作用2:字符串拼接

六、控制语句

1.怎么接受用户键盘输入?

java.util.Scanner s = new java.util.Scanner(System.in);

int i = s.nextInt();

String str=s.next();

2.控制语句

三类

  • 选择语句 if switch
  • 循环语句 for while do…while
  • 转向语句 break continue return
boolean sex =false;
if (sex){
	System.out.println("男");
}else{
	System.out.println("女");
}
//可以进一步改良
//可以使用三目运算符
System.out.println(sex ? "男":"女");

switch语句,支持int类型以及string类型

 switch(){
 case1:
 	java语句
 	break
 case2:
 	java语句
 	break
 case3:
 	java语句
 	break
 default:
 	java语句
 }
拿值与值1进行比较,如果相同,则执行该分支的java语句
case穿透现象,若没有break,则直接执行下一个case里面的java语句,不会在进行比较。
例
java.util.Scanner s = new java.util.Scanner(System.in);
int num =s.nextInt();
switch(num){
case 0:
	System.out.println('星期日')
	break
case 1:
	System.out.println('星期一')
	break
case 2:
	System.out.println('星期二')
	break
case 3:
	System.out.println('星期三')
	break
case 4:
	System.out.println('星期四')
	break
case 5:
	System.out.println('星期五')
	break
case 6:
	System.out.println('星期六') 
}

循环语句

for(int i=0;i<100;i++){

​ System.out.println()

}

for(初始化表达式;条件表达式;更新表达式){循环体}

do while

语法机制

do{
	循环体;
}while(布尔表达式);

先执行循环体的代码,之后判断布尔表达式结果,如果为true,则继续执行,到false结束。

转向语句

break用在两个地方,一是switch,用来终止switch语句的执行;二是用在循环语句中,用来终止循环的执行。

七、方法

main方法jvm会自动调用,除此之外的其他方法都需要程序员手动调用

java的方法相当于c语言或python的函数。

1.方法怎么定义,语法机制是什么?

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

方法体

}

当一个方法执行结束不返回任何值的时候,返回值类型写void关键字

有返回值类型时,方法里必须有return并且返回相应类型的结果

形式参数列表中的每个参数都是“局部变量”,方法结束后内存释放,形参的个数是:0~N个。

public static void sumInt(int x,int y){}

return用来终止离它最近的一个方法

JVM(java虚拟机)

  1. 栈 stack:在方法被调用的时候,该方法需要的内存控在栈中分配
  2. 堆区
  3. 方法区:类加载器classloader,将硬盘上的xxx.class字节码文件装载到jvm的时候,会将字节码文件存放到方法区当中,也就是说方法区中储存的是代码片段

常见的数据结构

数组、链表、图、二叉树、栈、队列…

和数据结构通常一块出现的是算法

排序算法、查找算法…

方法只有在调用的时候才会在栈中分配空间,并且调用时是压栈。执行结束后,该方法所需的空间就会释放,此时发生弹栈动作。
在这里插入图片描述

方法重载机制

功能相似的,可以让方法名相同,更易于代码编写。

在同一个类当中,如果“功能1”和“功能2”它们的功能是相似的,那么可以考虑将它们的方法名一致。

  1. 在同一个类中
  2. 方法名相同
  3. 参数列表不同(参数个数不同,类型不同,顺序不同都算不同)

方法递归

方法自己调用自己,这就是方法递归。

如果遇到stackoverflowerror

  1. 先检查递归的结束条件是否正确
  2. 手动调整JVM的栈内存初始化大小。可以将栈内存空间调大些。
  3. 调整了大小,如果运行还是出现这个错误,继续调整栈的内存大小 java -X可以查看
public clss RecursionTest03{
    public static void main(String[] args){
        int dd = sum(3);
        S.p(dd);
    }
    public static int sum(int n){
        if(n==1){
            return 1;
        }
        return n + sum(n-1);
    }
}

八、认识面向对象

  1. c语言是完全面向过程
  2. c++一般面向过程,一半面向对象
  3. java完全面向对象

面向过程的优点(快速开发)

  • 对于小型项目,采用面向过程的方式,效率高。不需要前期进行对象的提取,模型的建立。

面向对象的三个术语

  1. OOA:面向对象分析
  2. OOD:面向对象设计
  3. OOP:面向对象编程

实现一个软件的过程:

分析(A)–>设计(D)–>编程(P)

PM项目经理 Project Manager

面向对象包括三大特征

  1. 封装
  2. 继承
  3. 多态

类:人类大脑思考总结的一个模板

对象:实际存在的个体

实例:对象的另一个名称

实例化:通过类这个模板创建对象的过程

抽象:多个对象具有共同特征,进行思考总结抽取共同特征的过程

九、对象的创建与使用

类的定义
[修饰符列表] class 类名{
    // 类体=属性+方法 
    // 属性在代码上以“变量”的形式存在
    // 方法描述动作/行为
}
Student s1 = new Student();

类名 变量名= new 类名();

凡是通过new运算符创建的对象,都存储在堆内存中,new运算符的作用就是在堆内存中开辟一块空间

栈中主要存储局部变量

变量必须先声明,再赋值才能访问

对于成员变量来说, 没有手动赋值时,系统默认赋值

不能通过类名直接访问实例变量

像s1这种变量,保存了对象内存地址的变量,有一个特殊的名字:引用
在这里插入图片描述

构造方法
  1. 通过构造方法可以完成对象的创建,以及实例变量的初始化。换句话说,构造方法是用来创建对象,并且同时给对象的属性赋值
  2. 当一个类没有提供任何构造方法,系统会默认提供一个无参数的构造方法。该方法被称为缺省构造器。
  3. 调用构造方法,使用new运算符 new 构造方法名(实际参数列表)
  4. 语法结构?
[修饰符列表] 构造方法名(形式参数列表){
    构造方法体
}
  • 修饰符列表目前统一写public,不要写public static
  • 构造方法名和类名必须一致
  • 构造方法不需要制定返回值类型,也不能写void,写上void表示普通方法,就不是构造方法了。
[修饰符列表] 返回值类型 方法名(形式参数列表){
    方法体
}

成员变量,当构造方法里什么都没写,会默认成员变量会默认值。

构造方法的作用

  1. 完成对象的创建
  2. 给属性(实例变量)初始化

十、封装

作用两个

  1. 保证内部结构安全
  2. 屏蔽复杂,暴露简单

封装流程

  1. 属性私有化,使用private关键字进行修饰
  2. 对外提供简单的操作入口
封装前
public class PersonTest{
    public static void main(String[] args){
        Person p1 = new Person();
        S.p(p1.age);
        p1.age=-100;
        S.p(p1.age);
    }
    public class Person{
    int age
	}
}

封装后
public class PersonTest{
    public static void main(String[] args){
        Person p1 = new Person();
        S.p(p1.age);
        p1.age=-100;
        S.p(p1.age);
    }
    public class Person{
    private int age
    // 对外提供简单的访问入口
    // 外部程序只能通过调用以下的代码来完成访问
	}
}

带有static的方法,通过“类名.”方式访问

将构造方法中class换成void变成实例方法

对象又被称为实例,有实例方法、实例变量。实例对象必须创建对象后,才能通过“引用.”的方法访问实例方法

空引用访问“实例相关的数据”,会出现空指针异常

set方法和get方法
public calss Person{
    private int age;
    
    public int getAge(){
        return age;
    }
    public void setAge(int nianLing){
        age = nianLing;
    }
}
/*set 方法和get方法需满足一下格式
get方法要求
public 返回值类型 get+属性名首字母大写(无参){
	return xxx;
}
set方法要求
public void set+属性名首字母大写(有一个参数){
	xxx = 参数;
}
*/
//升级
public calss Person{
    private int age;
    
    public int getAge(){
        return age;
    }
    public void setAge(int nianLing){
        if(nianLing<0 || nianLing>150){
            S.p("年龄不合法,请重新赋值");
            return;
        }
        age = nianLing;
    }
}
外部读取
public class PersonTest02{
    public static void main(String[] args){
        Person p1 = new Person();
        int nianLing = getAge();
        S.p(nianLing);
        //相当于
        S.p(p1.getAge());
        p1.setAge(100);
        S.p(p1.getAge());
        
        
    }
}

十一、this和static

  1. static翻译为“静态”
  2. 所有static关键字修饰的都是类相关的,类级别的
  3. 所有static修饰的,都是采用“类名.”方式访问
  4. static修饰的变量:静态变量
  5. static修饰的 方法:静态方法

根据变量声明的位置可以划分为局部变量和成员变量,而成员变量又可以分成实例变量和静态变量。实例变量采用“引用”的方法访问

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

静态变量也可以用“引用”的方法访问,不过建议不这么写,会引起误解,使程序员认为是实例的变量。

静态代码块

static{

}

static在main方法之前执行,自上而下执行。

该代码不常用,作用:给java程序员的一个特殊时机,这个时机叫做:类加载时机。

记录一下类加载的日志信息(在哪年哪月哪日…哪个类加载到JVM当中)

实例语句块

语法就一个大括号{}

在构造方法之前执行 ,作用当有多个构造方法时,且构造方法中开头有相同的代码,可以提取相同代码放入实例语句块

this

this只能用在实例方法中,谁调用这个实例方法,this就是谁。this代表的是:当前对象。

作用:当方法中要用到对象实例变量,而对象还没创建出来时,怎么写,this.实例变量,可以省略。(实例变量必须采用“引用”的方式访问)

this不能出现在静态方法中,this表示当前对象,静态方法中不存在当前对象

不能省略this的情况

public void setName(String s){
    name =s;
}
//可读性更强的写法
public void setName(String name){
    this.name = name;
}  

this()的用法

public class thistest(){
    public static void main(String[] args){
        
    }
}
class Date{
    private int year;
    private int month;
    private int day;
    public Date(){
        this.year = 1970;
        this.month = 1;
        this.day=1;
        //以上三行另一种写法:this(1970,1,1) 注:该写法必须写在首行
    }
    public Date(int year,int month,int day){
        this.year =year;
        this.month = month;
        this.day=day;
    }
    public void setYear(int year){
        this.year = year;
    }
    public int getYear(){
        return year;
    }
    public void setMonth(int month){
        this.month = month;
    }
    public int getMonth(){
        return month;
    }
    public void setDay(int day){
        this.day = day;
    }
    public int getDay(){
        return day;
    }
    public void detail(){
        S.p("打印输出年月日")
    }
}
  1. this是一个关键字
  2. this可以使用在实例方法中,也可以使用在构造方法中
  3. this出现在实例方法中表示当前对象
  4. this不能出现在静态方法中
  5. 大部分时间可以省略,但是用来区分局部变量和实例变量的时候不能省略
  6. this() 这种语法只能出现在构造方法第一行,表示当前构造方法调用本类其他的构造方法,目的是代码复用

十二、继承

子类继承父类,除了构造方法全部继承过来。

凡是采用“is a”能描述的,都可以继承。例如:

猫是一个动物

狗是一个动物

信用卡账户是一个银行账户…

JDK源码所在位置java/jdk-17/lib/src.zip

System.out.println(); 这里system是一个类,out属于静态变量

十三、方法覆盖和多态 ***

1.什么时候考虑使用方法覆盖?

2.什么条件满足的时候构成方法覆盖?

3.关于object类中toString()方法覆盖?(toString的作用…大多数java类toString方法都需要覆盖,因为object类中提供的toString方法输出的是一个java对象的内存地址)

4.方法重载与方法覆盖有什么区别?(方法重载发生在同一个类中,方法覆盖发生在具有继承关系的父子类之间。条件不同…)

方法重载 overload

当在一个类当中,如果功能相似的话,建议将名字定义成一样,条件如下

  1. 在同一个类当中
  2. 方法名相同
  3. 参数列表不同
方法覆盖

当子类继承父类之后,当继承过来的方法无法满足当前之类的业务需求时,子类有权利对这个方法进行重新编写,有必要进行“方法的覆盖”

当子类对父类继承过来的方法进行“方法覆盖”后,继承过来的方法没了。

实行方法覆盖的条件

  1. 两个类必须有继承关系
  2. 重写之后的方法与之前的 方法必须满足方法名相同,参数列表相同,返回值类型相同
  3. 访问权限不能更低,可以更高
  4. 重写之后的方法不能比之前方法抛出更多的异常,可以更少

注意事项

  1. 方法覆盖只针对方法和属性无关
  2. 私有方法无法覆盖
  3. 构造方法不能被继承,所有构造方法也不能被覆盖
  4. 方法覆盖只是针对于实例方法,静态方法覆盖没有意义

toString 含义:调用一个java对象的toString()方法就可以将该java对象转换成字符串的表示形式

多态

❓ 问题

  1. 向上转型和向下转型的概念?
  2. 什么是多态?
  3. 什么时候必须用向下转型?(当你需要访问的是子类对象中“特有”的方法,此时必须使用)
  4. 为什么使用多态,而不是在创建对象时直接使用子类,多态还需向上转型,之后继续向下转型,多此一举。(在公司写代码时,你只参加部分方法的编写,而该方法编写时,你不清楚其他人要传入其中是什么,只知道是Animal这类下的子类,而具体是Bird类还是Cat类还是其他的不清楚,故此时需要用到向下转换)

在进行多态学习时需先掌握两个概念

  1. 向上转型 子 ---->父 类比(自动类型转换)
  2. 向下转型 父----> 子 (强制类型转换)

无论是向上还是向下转型,两类之间必须有继承关系。

public class test01
{
	public static void main(String[] args){
		Animal a1 = new Animal();
		a1.move();
		cat c1 = new cat();
		c1.move();
		Bird b1 = new Bird();
		b1.move();

		Animal a2 = new cat();
        //上面一行代码为向上转型
		a2.move();
        Animal a5 = new cat();
        a5.catchMouse();  //编译直接报错,因为编译器只知道a5是个Animal类,而Animal没有catchMouse方法,故编译报错
        cat x = (cat)a5; //向下转型,因为两者之间存在继承关系故不报错。
        x.catchMouse();
	}
}

多态指的是:父类型引用指向子类型对象,包括编译阶段和运行阶段。编译阶段:静态绑定父类 的方法。运行阶段:动态绑定子类型对象的方法 。多种形态。

Animal a6 = new Bird();

cat y = (cat)a6;

y.catchMouse();

会出现一个异常名为:java.lang.ClassCastException类型转换异常 ***经典异常 与空指针异常一样非常重要

instanceof(运行阶段动态判断)
  1. instanceof可以在运行阶段动态判断引用指向对象的类型
  2. instanceof的语法:(引用 instanceof 类型)
  3. instanceof运算符的结果只有true或false
  4. c是一个引用,c变量保存了内存地址指向了堆中的对想,(c instanceof Cat)返回True表示c引用指向的堆内存中的java对象是一个cat。
if(a6 instanceof cat){
    cat y = (cat)a6;
    y.catchMouse();
}

当要用到向下转型时,一定要使用instanceof运算符进行判断,可以有效避免类型转换异常

多态在开发中的作用 *********

作用:降低程序的耦合度,提高程序的扩展力。

public class test
{
	public static void main(String[] args){
		Master zhangsan = new Master();
		Dog caiQuan = new Dog();
		zhangsan.feed(caiQuan);
		Cat lanMao = new Cat();
		zhangsan.feed(lanMao);
	}
}
public class Master
{
	public void feed(Cat c){
		c.eat();
	}
	public void feed(Dog d){
		d.eat();
	}
}
//以上代码,需对Master进行较多的修改,如果主人又喜欢上了小猪,那么Master类中还需要再次重构方法,可以使用多态如下,先生成一个大类
public class Pet
{
	public void eat(){}
}
public class Master
{
	public void feed(Pet p){
		p.eat();
	}
}
//然后子类都继承父类即可,此时master无需再多做变动

私有方法不能覆盖

//方法重构时,返回值类型变小是可以的,变大不行。

十四、super

super和this对比着学习

this:

  1. this能出现在实例方法和构造方法中
  2. this的语法是:this. 和this()
  3. this不能出现在静态方法中
  4. this大部分情况可省略
  5. this在区分局部变量和实例变量时不能省略
  6. this()只能出现在构造方法第一行

super:

  1. super能出现在实例方法和构造方法中
  2. super的语法是:super. 和super()
  3. super不能出现在静态方法中
  4. super大部分情况可省略
  5. super …可以省略
  6. super()只能出现在构造方法第一行,通过当前的构造方法去调用“父类”中的构造方法,目的是:创建子类对象的时候,先初始化父类型特征

super()表示通过子类的构造方法调用父类的构造方法。模拟现实世界中:要有儿子,需要现有父亲

super();会默认出现在构造方法第一行,就像是没有构造方法时,会默认一个无参数构造方法。

super(实参)的作用是:初始化当前对象的父类型特征

super什么时候不能被省略?java允许父类和子类出现同名的变量,如果想在子中访问父的特征,super不能被省略
在这里插入图片描述
只写this和this.toString是一样的,但是super是不能单独用,必须在使用时加点

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值