JAVA小白随笔

JAVA前言: 

一、Java 的JDK java开发者工具包

  使用旧版的jdk是为了稳定 而不是使用新的版本的jdk 后者没有经过太多市场检验

二、JAVA的使用顺序:

  计算机能直接读懂二进制的字节码文件 所以要编译之后才可运行

 

三、JDK有哪些组成:

jvm虚拟机:真正运行java程序的地方,一次编译,就可以在jvm的系统平台运行。

核心类库:java自己写好的一些程序,给咱们自己的程序调用的

开发工具:javac、java、....

四、IDEA基操

包名一般把网站域名倒过来写

输入psvm/main回车 、sout是输出简写 refactor可以改类名,每一个类文件必须得有main方法 可以直接写main然后直接回车

导入模块:

准备模块、找到位置信息、从file---->New------>Module from Existing S...----->输入地址---->从iml文件导入(关联导入,未进入工程类目下)

永远不会丢的导入模块方法:首先把这个模块复制到这个工程类目之下 再重复差上述步骤 输入地址...那一套

快速调出解决问题的方案快捷键:Alt+Enter

ctrl+alt+t键 可以快速添加比如while 等结构

快速打出来for循环 在要使用for循环的语句后面加上 .fori 语句回车自动生成 循环语句

五、快速设置 getset方法 :

首先右键找到 generate

点进去再去点击getter and setter

把所需要的变量一一选中

Java正文

一、注释

注释不会出现在class字节码文件里面

注释:Ctrl+/ (单行多行) Ctrl+Shift+/多行注释

二、字面量

整数、小数、字符(程序必须使用单引号)、字符串(双引号内容可有可无)、布尔值、空值

特殊字符\n是换行 、\t是代表的一个tab 往后缩进了一格

三、变量

1.简介

int、double、boolean......

1 Byte 字节是 八位

变量是从{ }范围内有效 idea可以单单只写{ } ,变量不可以重复定义

字符在计算机的储存方式是ASCLL编码表 字符可以直接相加减 ‘a’ + 10 = 107

2.关键字和标识符

不可以命名的单词

基本组成:由数字、字母、下划线(_)和美元符号组成

强制要求:不可以以数字开头、且是区分大小写

3.自动类型转换

类型范围小的变量,可以直接赋值为范围大的变量

byte、char、short ---->int ------>long----->float ---->double

char ch ='a'; int i=ch;

4.表达式的自动类型转换

表达式的最终结果类型是由表达式中的最高类型决定的

在表达式中,byte、short、char是直接转化为int类型参与运算的(因为担心这种小类型的变量相加之和溢出了 )

byte a=10int b=20; long c=30; long =a+b+c;//可以 byte i=10; short j=30; short rs3=i+j;//不可以因为此时i和j已经变成int类型了 int rs4=i+j;//可以 //在表达式中,byte、short、char是直接转化为int类型参与运算的

5.强制类型转换(大类型的变量转换为小变量类型解决方法)

直接赋值会报错怕溢出,所以要无视风险、继续操作、就好比小类型的那些框直接从从大类型直接框选

二进制的第一个位置是表示正负 所以下面的强制转换后是负数

浮点型强转为整形,直接保存整数部分返回

公式: 数据类型 变量2 = (数据类型)变量1 、数据

四、运算符

1、基本的算数运算符:+、-、*、/、%(取余)

+:加号是与字符串运算的时候是用作连接符的,其结果依然是一个字符串

对于除法 两个整数相除是一个整数没有小数位,可以把其中一个变量转换为浮点型 可以用1.0去乘以其中一个数再去相除

 

2.自增自减(++和--)

变量单独使用的话,放在变量前面和后面都可以、

要是不是单独使用的话就是先赋值再自加自减的区别

 

3.基本赋值运算符

4.关系运算符

5.逻辑运算符

6.三元运算符

格式:条件表达式?值1:值2;

首先执行条件表达式如果值为true,返回值是值1,如果是Flase ,返回值是值2

double score=58.5; String rs= score >=60 ? "成绩合格""成绩不合格";

五、接受键盘输入的数据

 

 

六、随机数Random

Random r=new Random(); int number=r.nextInt(10);//前闭后开 范围是0到9

括号里面是一个区间 可以通过增加减少 数字 来控制具体 区间值 比如取 58~70 之间的数 不包括70 首先 这个区间大小是12 所以 是 nextInt(12)+58 这个是 从0到11 所以:

Random r= new Random(); int num=r.nextInt(12)+58;

七、数组

1.初始化数组

int[] age=new int[]{12,23,12}; double []score=new double[]{11.3,1.23,34.23}; 简写: int age[]或者 int[] age 括号放在之前之后 都不影响

2.动态初始化数组

不存入数组具体的元素值 只确定数组的数据类型 以及长度

int a=new int[100];//int类型元素默认值是0

float、double 数组类型值默认值是0.0

boolean数组类型的默认值是false

八、JAVA内存分配介绍

九、方法

把一段代码封装成一个功能 以便重复使用

public static int qiuhe(int a,int b);{//形参 void ,没有返回值 int c=a+b; return c; } ...... 直接调用 int sum=qiuhe(100,232);

  1. 值传递

所谓值传递:指的是在传输实参给方法的形参的时候,传输的是实参变量找那个储存值的副本

局部变量,用完之后就销毁了。

 

变量只是用了个副本 但是数组是传递的指针 

int [] arr ={ };

这个数组虽然内部的值为空 但是不是null值

为了节省存储空间

2.方法重载

return :可以在无返回值的方法中立即跳出并且结束当前方法的执行

package com.baigan.first; import java.util.Scanner; public class Main { public static void main(String[] args) { int a=1,b=0; chu(a,b); } public static void chu(int a,int b){ if(b==0){ System.out.println("0不能做除数"); return; }else{ System.out.println(a/b); } } }

十、面向对象

1.基础知识

系统首先把类加载到方法区之中

new出来的会放到堆内存之中,堆内存会单独开辟出一块内存空间

main方法会提到栈内存执行

 

对象是引用类型的变量

一个代码文件中可以写多个class 但是只能有一个用public 修饰

 

对象和对象之间不会相互影响 但是多个变量指向同一个变量就互相影响了

Student s1=new Student(); Student s2=s1;//s2一开始是null值 但是s1将地址赋值给了s2

  

如果在后续操作之中 将对象的值变成null 那么在栈内存里面的对象指针 指向堆内存 的地址就清空了

2.关键字this

this 就是一个变量,可以用在方法中,来拿到当前对象

package com.baigan.first; public class duixiang { public static void main(String[] args) { Student stu=new Student(); System.out.println(stu); stu.shuchu(); } } class Student { public void shuchu(){ System.out.println(this); } } 输出结果是: com.baigan.first.Student@2f4d3709 com.baigan.first.Student@2f4d3709 Process finished with exit code 0

结论 就是 this 是一个拿到当前对象的地址

可以调用当前对象 的变量 以及方法

 

this应用场景:

1.解决变量名称冲突问题

构造器;

1.与类名完全一样且无返回值

2.构造器可以重载

3.存在有参构造起和无参构造起

创建对象时候会根据参数的多少自动调用构造器

类在设计的时候会自动生成一个无参构造器(不写构造器的话)

要是有有参数构造器就不会自动生成无参构造器了

所以要一般要手动写一个无参构造器

 

3.封装

合理隐藏 合理暴露

 

4.javabean

实体类

1.该成员变量都要 进行 私有化 不建议给初始值

2.对外必须提供相应的get×××以及set××× 方法 也就是设置数据 拿数据

3.类当中必须有一个无参的构造器

数据和数据业务处理应该分离开来

数据部分: class Student { private String name; private int age; public Student (){ } public Student(String name,int age ){ this.name=name; this.age=age; } public void setName(String name){ this.name=name; } public void setage(int name){ this.age=age; } public String getname(){ return name; } public int getAge(){ return age; } }
class Studentoperator { Student student; public Studentoperator() { } public Studentoperator(Student student) { this.student = student; } public void PANDUAN() { if (student.getAge() > 18) { System.out.println("太老了"); } else { System.out.println("好年轻"); } } }

注意不要把类写到类里面

 

十一、常用api

不要重复造轮子 ,直接拿过来用

这个地方可以选择一下 这个自动导包进来

十一、字符串

length、charAt、substring、replace、contain

1.获取字符串的长度:

String s="黑马java"; System.out.println(s.length);

2.提取字符串中某个索引处的字符

char c=s.charAt(1); System.out.println(c);

3.把字符串转换成字符数组,再去进行遍历

char []chars=s.toCharArray();

4.判断两个字符串内容,内容一样就返回true

直接用==号比较的话会返回false值 因为String是引用数据类型,所以比较的是地址

String s1="java"; String s2="JAVA"; boolean s3=s1.equals(s2); boolean s4=s1.equalsIgnoreCase(s2);//忽略大小写进行比较

5.截取字符串内容(前闭后开)

String s3="JAVA是最好的编程语言之一"; String rs= s3.substring(0,8); //也就是选中 从0到8索引下的一些字符串 //括号里面也可以只写一个表示从选中的字符一直到字符串的末尾 String rs1=s3.substring(4);

6.把字符串中某个内容替换成新内容并返回新的字符串内容给我们

就比如可以屏蔽脏话的功能一样

String says="这个电影简直是一个傻逼作品"; String changesays=says.replace("傻逼","**");

7.判断字符串里面是否包含某一个元素,返回值是一个bool值

String test="我喜欢打原神"; if(test.contains("原神")){ System.out.println("我抄!原!"); }

8.把字符串按照某个指定内容 分割成多个字符串,放到一个字符串数组中返回给我们

public static void main(String[] args) { String name="张三*李四*王二麻子*周三胖"; String[] name1=name.split("\\*");// for (int i = 0; i < 5; i++) { System.out.println(name1[i]); }

 

ps: +、*、|、\等符号在正则表达示中有相应的不同意义。用的时候加上“\\”或者“/”或者“[]”转义一下就可以了。

1、String使用注意事项:

String对象的内容不可以改变,被称为不可变字符串对象

只要是双引号引起来的字符串对象 ,会存储到字符串常量池,且相同内容的字符串只存储一份;

String a="java牛逼"; String b="java牛逼"; if(a==b){ System.out.println("地址相等"); }

但是通过new出来的方式创建字符串对象,每次new一次就会产生一个新的对象 放在堆内存之中

char[]chars={'a','b','c'}; String a1=new String(char)

凡是new出来的或者是 运算得出来的 都放在堆之中 凡是由双引号直接定义的放在常量池之中。

编码阶段s2只能是认为是符号 编译器一眼看不出来

十二、ArrayList

代表的是一种集合,集合是一种容器,用来装数据的,类似于数组

由数组就行了 为啥要集合?

就比如 购物车案例

初始化数组长度就固定了 但是用户要多加商品 长度不够用了怎么办,使用集合可以动态调整长度

集合的种类非常多,重点学习arraylist,经典操作就是增删改查操作,学习目标:

1.创建对象

2.增删改查的方法

3.容器的其他特点

若是直接输出集合对象 输出的不是集合对象的地址而是 这个集合里面所有的值

add、get、remove、set

一、创建对象基本操作

1.未约束集合存储的具体类型

ArrayList array=new ArrayList(); array.add("点头"); array.add("yes"); array.add("摇头"); array.add("no");// array.add(2829311); array.add(2829311.099999);

2.约束具体类型 的集合

ArrayList<String> array=new ArrayList<String>();//后面的<String>可以省略 array.add("点头"); array.add("yes"); array.add("摇头"); array.add("no"); array.add(2829311.999);//此处报错

二、往集合中的某个索引处位置添加一个数据

ArrayList<String> array=new ArrayList<String>(); array.add("点头"); array.add("yes"); array.add(1,"窝嫩叠");//相当于在位置是1的地方添加了“窝嫩叠”这个字符串

三、根据索引获取集合中的某个索引位置处的值

System.out.println(array.get(1));//使用get方法获取

四、获取索引的大小(返回值是集合中存储的元素个数)

System.out.println(array.size());//使用size方法获取

五、两种删除集合元素的方式

第一种是直接在remove方法之中添加需要删除的元素的索引 此时在调用方法之后会返回删除元素的具体值

ArrayList<String> array=new ArrayList(); array.add("点头"); array.add("yes"); System.out.println(array.remove(1));

第二种是直接在remove方法之中添加需要删除的元素 此时在调用方法之后会就近删除第一个改元素,并且返回一个是否是删除成功的boolean值

ArrayList<String> array=new ArrayList<String>(); array.add("点头"); array.add("yes"); array.add("点头"); System.out.println(array.remove("点头")); System.out.println(array); /*输出结果是: true [yes, 点头]*/

但是注意了 没一次删除元素之后 后面的元素就会向前填充刚才已经删除之后的那个位置 也就是索引会提前 跟数组不一样 数组删除之后索引对应的元素是固定的。

有需求: 删除集合当中 所有包含枸杞的元素

正序删除的时候索引的值会一直动态改变 所以容易出bug

改进版:倒序删除

ArrayList<String> array=new ArrayList(); array.add("Java入门"); array.add("宁夏黑枸杞"); array.add("山东枸杞"); array.add("窝嫩叠"); array.add("测试1"); for (int i = array.size()-1; i >=0 ; i--) { if(array.get(i).contains("枸杞")){ array.remove(i); } } System.out.println(array);

六、修改某个索引位置的数据,并且修改后返回原来的值(原先没修改之前的值)给我们

System.out.println(array.set(1,"玛卡巴卡"));

ATM系统实操:

略;

java高阶

static

叫静态,可以修饰成员变量、成员方法

成员变量按照有无static修饰,分为两种:

  1. 类变量:有static修饰,属于类,在计算机里面只有一份,会被类的全部对象共享,类变量可以使用类直接访问.

  2. 实例变量(对象变量):无static修饰,属于每个对象的,每个对象只有一份。

类变量的应用场景:

在开发中,如果某个数据只需要一份,且需要能够被共享(访问,修改),且该数据可以定义成类变量来记住。

比如:

系统启动后,要求用户类可以记住自己创建了多少个用户对象了。

new User(); public class User{ public static int number; public User(){ User.number++;// //此处可以省略User. 这个前缀不写 访问自己类的类变量,才可以省略类名不写 } }

每一次创建对象就自动调用无参构造器,而且是调用静态变量记录

类方法的常见应用场景;

做工具箱: 工具箱中的都是一些类方法,每个方法都是用来完成一个功能的,工具类是给开发人员共同使用的。

提高了代码复用性,调用方便,提高效率

为啥工具类中的方法要使用 类方法,但是不使用实例方法?

  1. 实例方法需要创建对象来调用,此时对象只是为了调用方法,对象占内存,这样会浪费内存。

  2. 类方法,直接用类名调用即可,调用方便,也能节省内存

所以说为了不让别人创建对象来访问,一般都将构造器私有化

不要私有化类名字

注意事项:

  1. 类方法中是直接可以访问类成员 比如变量方法

  2. 但是类方法中不可以访问实例成员,因为实例成员是属于对象的

  3. 实例方法可以调用类方法、实例方法、实例变量( 相当于前面多了个this ) 。

  4. 实例方法中可以出现this关键字,类方法中不可以出现this 关键词,this是跟对象紧密结合一起的

 

代码块:

代码块是类的5大成分之一(成员变量、构造器、方法、代码块、内部类);

两种 :

  1. 静态代码块:(了解即可用的很少)

格式:static{};

特点:类加载的时候,由于类只会加载一次,所以静态代码块只会执行一次

作用:完成类的初始化。可以直接访问类成员。例如:对类变量的初始化赋值

  1. 实例代码块:

    格式{}

    特点:每次创建对象的时候。执行实例代码块,并在构造器之前执行,这里的执行是逻辑上的先执行,而不是顺序方面的先执行。

    作用:和构造器一样,都是用来完成对象初始化的,例如:对实例变量进行初始化赋值,但是这样搞会把所有的对象的变量的值变成一样的

实际开发中,是用来记录创建对象日志,减少重复代码块

 

public class Student(){ private static Student student=new student(); //1.定义一个类变量记住类的一个对象 类变量是随类一起持有的,也就是类在初始化的时候。上面的只会执行一次也就是只会生成一个对象。 private Student(){ } //2.必须私有化类的构造器 public static student getObject(){ return student;//这里无论返回多少次返回的都是同一个对象 } //3.定义一个类方法返回类的对象 }

软件工程考试

单例 作用也是为了减少重复,节省开支。

下面是饿汉式单例模式:

想拿对象的时候,对象已经被设计好了

public static void main(String[] args){ Student student1=Studentv.getObject(); Student student2=Studentv.getObject(); System.out.println(student1); System.out.println(student2); //这俩输出的是一样的 }

懒汉式单例设计模式:

拿对象的时候,才开始创建对象,也就是一开始不创建对象

三步:

  1. 把类的构造器私有化。

  2. 声明一个类变量用于存储对象。

  3. 提供一个类方法,保证返回的是同一个对象。

public class Student(){ private static Student student; //1.定义一个类变量记住类的一个对象 类变量是随类一起持有的,也就是类在初始化的时候。上面的只会执行一次也就是只会生成一个对象。 private Student(){ } //2.必须私有化类的构造器,防止创建对象。 public static student getInstance(){ if(student==null){ student=new student(); } return student;//这里无论返回多少次返回的都是同一个对象 } //3.定义一个类方法, }
public static void main(String[] args){ Student student1=Student.getInstance(); Student student2=Student.getInstance(); System.out.println(student1); System.out.println(student2); //这俩输出的是一样的 }

 

继承:
  1. 权限修饰符

  2. 单继承、object类

  3. 方法重写

  4. 子类中访问其他成员的特点

  5. 子类构造器的特点

  6. 注意事项小结

 

 

 

继承的基础知识

子类能够继承父类的非私有成员(成员变量、成员方法)。

子类的对象是由子类、父类共同完成的

子类的每一个构造器如果不声明,都会隐式的继承父类的无参构造器

1.权限 修饰符

 

其中注意protected 是在任意包下面的子类当中的情况中,只可以让他自己的子类使用的,只要不是子类哪怕在外面创建的一样不能使用

在开发中,一般用的最多的是public和private

2.单继承、object类

1.java是单继承的、一个类只能继承一个类,java不支持多继承 但是支持多层继承

2.Object类是Java中所有类的祖宗类 每一个类都直接或者间接的继承这个类

3.方法重写

当子类觉得父类的某个方法不好用,或者无法满足自己的需求时,子类可以重写一个方法名称、参数列表一样的方法,去覆盖父类的这个方法,这就是方法重写。

注意:重写之后,方法的访问,java会遵循就近原则

方法重写的其他注意事项:

1.重写的时候加上@Override注解 加上之后有两个优点,一个是可以帮忙检测重写的是否写错了,另一个是可读性更高,看了之后就知道是重写

2.子类重写父类方法时候,访问权限必须大于或者2等于父类该方法的权限(public>protected>缺省)

3.重写的方法返回值类型,必须与被重写方法的返回值类型一样,或者范围更小

4.私有方法、静态方法不能被重写,如果重写会报错

 

方法重写的真实案例

 

重写object类里面的tostring方法,使对象更有辨识度,将来可以直接输出该对象的tostring或者对象 本身就可以知道该对象包含的内容是是啥

要是直接用print输出对象此时会调用该对象的tostring方法 将该方法的地址输出出来

快捷重写tostring的方法是右键选出generate里面有个tostring 框选出所有的方法变量 直接回车

3.子类中访问其他成员的特点:

就近原则:

在子类方法中访问其他成员(比如成员变量和成员方法)是按照就近原则。

  1. 先按照局部去找

  2. 然后子类成员范围找

  3. 然后父类成员范围找,如果找到父类范围还没有找到则报错

    如果子父类中,出现了重名的成员,会优先使用之类的,如果此时一定要在子类中使用父类的怎么办?

    可以通过super关键字,指定访问父类的成员:super.父类的成员变量/父类成员方法。

  4. 子类 构造器的特点

    1.子类的全部构造器,都会先调用父类的构造器,再去执行自己

    也就是子类的所有的构造器会先去调用父类的无参构造器,默认在构造构造器第一行都有一行super()的字段,所以说要在一般写类的时候都加上无参构造器。

  5. 要是父类没有无参构造器(自己写一个构造器的话,2那么父类的构造器就会被盖住)这个时候可以在子类的构造器的第一行手写super(····) 括号里面根据父类的手写的那个构造器来写参数

就比如

父类: public F(String name,int age); · · ······· 子类里面: public Z(){ super("波妞",18); ······· · · }

也可以在子类构造器里面直接利用父类的构造器给变量赋值

父类: public People(String name, int age, double high) { this.name = name; this.age = age; this.high = high; } 子类: Teacher (String schoolname,String name,int age,double high){ super(name,age,high); this.schoolname=schoolname; }

但是在创建对象的时候要在创建的开始就利用构造器赋值

为啥会出现上面的反复调用的现象呢?

由于对象的构造器被拆分到多个类里面去了,子类需要调用父类构造器才能将全部初始化的动作完成

 

补充知识:

this(··········)

可以在this括号里面填上参数,以此来调用自己的类里面的其他构造器

也就是要是构造器参数类型数量不一样,可以使用this来调用本类里面的其他构造器

但是this和super不可以同时出现,要是出现的话必须写在构造器的第一行。


 

目录:

 

  • 面向对象的三大特征之三:多态

  • final

  • 抽象类

    • 认识抽象类

    • 使用抽象类的好处

    • 抽象类的常见应用场景:模板方法设计模式

  • 接口

 

面向对象的三大特征之三:多态
  1. 认识多态

    在继承/实现情况下的一种状态,表现为:对象多态、行为多态。

代码举例:

public class Main { public static void main(String[] args) { People p1=new Teacher(); p1.run(); People p2=new Student(); p2.run(); } } class People { public String name="父类People的名称" public void run(){ System.out.println("人可以跑"); } } class Student extends People{ @Override public void run(){ System.out.println("跑的贼快"); } } class Teacher extends People{ @Override public void run(){ System.out.println("跑的气喘吁吁"); } }

此时输出结果是:

老师跑的气喘吁吁 跑的贼快

都是人的行为 但是在不同的对象下表现出不同的状态 这就是行为多态,

技巧:编译看左边,运行看右边

写的时候得看People类里面有没有run方法 但是实际跑的时候得看后面的类

不限于run方法 只要是在父类里面没有这个方法,即使是在子类里面有 以下面的格式创建对象的时候无法运行

  • 情况1:子类有该同名函数,父类没有,会报错

  • 情况2:子类没有该同名函数,父类有该函数,会按照父类的函数执行。

  • 情况3:子类和父类都有该同名函数,会按照子类的函数情况来。

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

多态的前提:有继承/实现关系;存在父类引用子类对象;存在方法重写。

多态的一个注意事项:

多态是对象、行为的多态,java中的属性(成员变量)不谈多态

public class Main { public static void main(String[] args) { People p1=new Teacher(); System.out.println("p1.name"); People p2=new Student(); System.out.println("p2.name"); } } class People { public String name="父类People的名称" public void run(){ System.out.println("人可以跑"); } } class Student extends People{ public String name="子类Student的名称" @Override public void run(){ System.out.println("跑的贼快"); } } class Teacher extends People{ public String name="子类Teacher的名称" @Override public void run(){ System.out.println("跑的气喘吁吁"); } }

输出结果是:

父类People的名称 父类People的名称

对于变量编译看左边,运行看左边

 

使用多态的好处:

1.在多态形式下,右边对象是解耦合,更便于扩展和维护,就比如在开车的时候我们的车胎可能会爆炸,但是轮胎就可以方便更换,这就是解耦合。

 

  • 在多态形式下,右边的对象是解耦合的,更便于扩展和维护。

 

People p1=new Student(); p1.run()
  • 定义方法时,使用父类类型的形参,可以接收一切子类对象,扩展性更强,更便利。

2.可以使用父类类型的变量作为形参,可以接收一切子类对象。

使用多态会产生一个问题,怎么解决

  • 多态下不能使用子类的独有功能

解决方法:

可以使用类型转换,

  • 自动类型转换:父类 变量名 =new 子类();例如: People p=new Teacher();

  • 强制类型转换:子类 变量名 =(子类) 父类变量例如: Teacher t=(Teacher)p;

强制类型展缓的注意事项

  • 编译阶段有继承或者实现关系就可强制转换但是运行的时候可能会出现类型转换异常,说白了就是能编译过,但是可能出现异常

  • 运行时候,如果发现对象的真是类型与强转之后的类型不同,就会报转换异常(ClassCastException)

People p1=new Student(); //强制类型转换 Student s1=(Student)p1; //报错ClassCastException 异常 Teacher t1=(Teacher)p1;

所以为了解决不知道当前对象类型的问题,java提供了 instanceof 关键字,先判断当前对象的类型再去进行强转

语法:p(对象变量)instanceof 类

如果p对象变量是后面的类或者是后面类的子类 那么就会返回True 否则就是false

所以在强制类型转换的时候应该这样:

People p1=new Student(); //强制类型转换 Student s1=(Student)p1; //报错ClassCastException 异常 Teacher t1=(Teacher)p1; if(p1 instanceof Student){ Student S2=(Student) p1; s2.test();//此时就可以使用子类的独有方 }else{ Teacher t2=(Teacher) p1; t2.teach() }

对象回调:

 

在接收参数时候 形参指向传进来的对象的地址 并指向原始对象变量地址,实际上就是对原先的对象变量进行操作

 

final关键字

final知识点,就是类似于const 常量修饰:

  • final关键字是最终的意思,可以修饰(类、方法、变量)

  • 修饰类的话:该类被称为最终类,特点是不能被继承了

  • 修饰方法的话:该方法被称为最终方法,特点是不能被重写了。

  • 修饰变量:该变量只能被赋值一次,而且必须得赋值。

final修饰变量的注意:

  • final 修饰基本类型的变量,变量存储的数据不能被改变。

  • 但是修饰引用类型的变量,变量存储的地址不能被改变,但是地址所指向的地址可以被改变。

常量static final

  • 使用tatic final修饰的成员变量就被称为常量;

  • 作用:通常用于记录系统的配置信息

比如

  • 程序被编译之后,常量会被"宏置换":出现常量的地方全部会被替换成其记住的字面量,说人话就是SCHOOL_NAME直接就是QUST。

public static fianl String SCHOOL_NAME="QUST";

注意:常量名的命名规范:建议使用大写英文单词,多个单词使用下划线连接起来

 

抽象类

一、抽象类简介

  1. 认识抽象类

  • 在java中有一个关键字叫:abstract,他就是抽象的意思,可以用它修饰类、成员方法

  • abstract修饰类,这个类就是抽象类,修饰方法,这个方法就是抽象方法

抽象方法只有方法签名 不能有方法体

  1. 抽象类的注意事项、特点

  • 抽象类中不一定有抽象方法,但是有抽象方法的类一定是抽象类,说人话就是抽象类里面可以有抽象方法也可以没有,要是有抽象类子类必须给实现 相当于设置了一个壳子 等着子类填充。

  • 类该有的成员(成员变量、方法、构造器)抽象类都可以有

  • 抽象类的最主要特点:

    • 抽象类不能创建对象,仅仅作为一种特殊的父类。让子类继承并且实现

  • 一个类继承抽象类,必须重写完抽象类的全部抽象方法,否则要是不把这个类的抽象方法重写的话,这个类也得定义成为抽象类,抽象不能实例化,不能具体化 只能靠其他子类给全部具体实现

 

写类的时候方法

 
abstract class A{} 或者 public abstract class A{}

二、抽象类 的应用场景还有好处

  • 父类知道每个子类都要做某个行为,但每个子类要做的情况不一样,父类就定义成抽象方法,交给子类去重写实现,我们设计这样的抽象类,就是为了更好的支持多态。

  • 编译的时候看父类有没有,实际运行是调用子类;

     

    就比如下面猫和狗都有名字,但是叫声不同

abstract class Animal{ private String name; public abstract void cry(); } class cat extends Animal{ @Override public void cry() { System.out.println("小猫喵喵叫"); } } class dog extends Animal{ @Override public void cry() { System.out.println("小狗汪汪叫"); } }

三、 模板方法就是提取多个类的公共功能,应该用final修饰,防止其他子类给他重写。

 

 

接口

public interface 接口名{

//成员变量(也就是常量 idea自动用 static final修饰的,也就是说在写接口的时候写变量要赋初始值)

//成员方法(抽象方法)

}

  1. 注意:接口不能创建对象;接口是用来被类实现(implements)的,实现接口的类称为实现类。

    格式:

    修饰符 class 实现类 implements 接口1,接口2,接口3,…{

    }

  2. 一个类可以实现多个接口(接口可以理解成干爹),实现类实现多个接口,必须重写完全部接口的全部抽象方法,否则实现类需要定义成抽象类。

快速重写抽象方法的方法:按住alt+回车;在标红的地方。

接口的好处:

  1. 弥补了单继承的不足,一个类可以实现多个接口

  2. 让程序可以面向接口编程,这样程序员就可以;灵活方便的切换各种业务实现

面向接口的综合案例:

略。

把接口对象比喻成一个集大成者 可以随便选择不同的工具

 

接口从jdk8开始的新特性:

 

 

1、JDK8开始,接口中新增了哪些方法?

  • 默认方法:使用default修饰,使用实现类的对象调用。

  • 静态方法:static修饰,必须用当前接口名调用

  • 私有方法:private修饰,jdk9开始才有的,只能在接口内部被调用, 他们都会默认被public修饰。

2、JDK8开始,接口中为啥要新增这些方法? 增强了接口的能力,更便于项目的扩展和维护。

 

接口的多继承:

  • 一个接口可以同时继承多个接口

interface A{}; interface B{}; interface c{}; interface D extends C,B,A{}

可以让一个接口去整合合并其他接口 ,便于类的实现。

  • 一个类实现多个接口或者是一个接口继承了多个类 要是这几个接口里面的方法名一样 但是返回值不一样,这个时候就会报错

  • 一个类实现了多个接口,多个接口存在同名的(返回值类型和方法名都要一样)默认方法,可以不冲突,这个类可以重写该方法即可。

 

 

内部类

匿名内部类

  • 就是一种特殊的局部内部类;所谓匿名:指的是程序员不需要为这个类声明名字

  • 说白了就是在生成对象的时候的后面加了一堆{ }括号。然后再括号里面一般是重写类的方法或者是接口的方法。

  1. 书写格式:

new 类或者是接口(参数值){ 类体方法,一般是方法重写 }
People a=new People(){ @Override public void cry(){ } };
  1. 匿名类有啥特点:

    • 匿名类本质就是一个子类,并且会立即创建一个子类对象

  2. 匿名类有啥作用、应用场景?

    • 可以更方便的创建一个子类对象

    • 匿名类通常作为一个参数传输给方法

枚举

枚举是一个特殊类

枚举的格式:

修饰符 enum 枚举类名{ 名称1、名称2、----; 其他成员--- } public enum A{ X,Y,Z; ---- }

 

1.第一行写不写都是常量,无论写几个记住的都是当前枚举类的对象变量。

2.构造器写不写都是私有的,不能对外面构建对象。

枚举的常见应用场景:

 

 


__EOF__

本文作者孙佰淦
本文链接https://www.cnblogs.com/lllusionary/articles/18014905.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   皮卡Q  阅读(13)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
点击右上角即可分享
微信分享提示