文章目录
String new和 String的区别
public static void main(String[] args) {
// String 既然是一个类,s1应该叫做String类的对象
// 属性=成员变量
// 类如果创建对象,new,s1并没有new,s1也可以叫做对象
String s1 ="asdf";//1
String s4 ="asdf";//4
// s2 是通过new创建出来的String的类
// 创建对象是要调用的构造器
String s2 = new String("asdf");//2
String s3 = new String("asdf");//3
// 1和2不是一个意思,虽然内容一样
// s1和s2指向不在同一区域内
// 双等号比较的是虚地址
// 虚地址:对象在内存的存储位置
// 有new就代表新建2和3就不一样
System.out.println(s1==s2);
System.out.println(s2 == s3);
System.out.println(s1 == s4);
// 1和4 相等没有new
}
String常用方法
-
比较字符串的内容: equals方法(代码一)
-
取出指定下标位置是字符:charAt方法(代码一)
-
判断指定字符是否存在 :indexOf方法(代码一)
-
字符串的截取 :str.substring方法(代码二)
-
下面所有方法都是返回新的字符串
-
转大写 :toUpperCase()方法(代码三)
-
转小写:toLowerCase()方法(代码三)
-
判断是否以XX开头:startsWith()方法(代码三)
-
判断是否以XX结尾:endWith()方法(代码三)
-
忽略大小内容比较:equalsIgnoreCase()方法(代码三)
-
去掉字符前的空格:trim()方法(代码三)
-
根据指定字符分割,分割之后,分割条件是消失 String [] strings = str3.split(","); for (String string : strings) { System.out.println(string); }
-
字符串替换:replace()方法 repalceAll()(代码三)
-
字符串转换其他类型:valueOf()方法(代码三) 字符串和其他类型的转换 int i = 10; 任何数据类型和字符串类型做加法,结果都是字符串 阿里规约不允许用这个方法String s = i + "i";//" "空串可以指针,“null”空指 针异常 String s = String.valueOf(i); System.out.println(s);
-
字符转数组:toCharArray()方法(代码三)
-
转字节型数组:getBytes()方法(代码三)
代码一
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
//第一个方法
// String s1 = "a";
// String s2 = "a";
// Scanner sc = new Scanner(System.in);
// System.out.println("请输入字符串1");
// String s3 = sc.next();
// System.out.println("请输入字符串2");
// String s4 = sc.next();
// 比较字符串的内容
/* equals方法
* 1.需要传参,传String类型的参数
* 2.有返回值,返回值是boolean类型
* 3.访问权限:public
*
* */
// System.out.println(s3.equals(s4));
String s1="abcdefgaaa";
// 取出指定下标位置是字符
s1.charAt(0);
// 字符串长度,返回值整型
// 访问权限public
/*
* 字符串的长度方法和数组获取长度有什么区别
* 数组的length是属性,String 的length()是方法
*
* */
System.out.println(s1.length());
// 取出指定下标位置的字符
System.out.println(s1.charAt(0));
char c = sc.next().charAt(0);
// char 类型可以转成数字
System.out.println(c+1);
// 判断指定字符是否存在,返回值为字符串在s1的下标
// 返回从左到右遇到的第一个匹配下标
// 如果不在返回-1
// indexOf(String,int)代表从int开始找,包括当前位置
System.out.println(s1.indexOf("a",8));
System.out.println(s1.lastIndexOf("a",12));
// 下标永远都是从左到右
}
练习题
**
练习一统计字符串出现的次数
**
方法一
public int sum(String target,String str){
int i= 0;
int times = 0;
while (i<str.length()){
int i1 =str.indexOf(target,i);
if (i1 !=-1){
times++;
i=i1+1;
}else {
i++;
}
}
return times;
}
public static void main(String[] args) {
Test01 t = new Test01();
t.sum("a","aewfaeawef");
System.out.println(t.sum("a","aewfaeawef"));
}
方法二
String s1="abcdefbbgaaa";
char target = 'b';
int count = 0 ;
// 第一种 for
for (int i = 0; i < s1.length(); i++) {
if (s1.charAt(i) == target){
count++;
}
}
System.out.println(target + "在" + s1 + "中间出现了" + count);
// 第二种 while
int i= 0;
int times = 0;
while (i<s1.length()){
int i1 =s1.indexOf(target,i);
if (i1 !=-1){
times++;
i=i1+1;
}else {
i++;
}
}
System.out.println(target + "在" + s1 + "中间出现了" + times);
代码二
public static void main(String[] args) {
// 字符串的截取
String str = "asdfafaefa";
/*
* 如果传一个参数,从指定位置开始截取,直到字符串的末尾
* 包不包括i的位置,包括起始位置字符
* 生成新的一个字符,不会改变原有数据
* */
// 截取下标1以后的内容
String s = str.substring(1);
// 截取下标1
s = str.substring(1,2);
System.out.println(s);
}
练习题
练习二根据身份证号拿去生日性别
public String hb(String sf){
String hb ;
hb = sf.substring(6,14);
return hb;
}
public String xb (String sf){
String xb = sf.substring(16,17);
int a = Integer.parseInt(xb);
String c ;
if (a%2==0){
c = "女";
}else {
c = "男";
}
return c;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入身份证号");
String sf = sc.next();
Test02 t = new Test02();
if(sf.length()==18){
System.out.println("生日:"+t.hb(sf)+" "+"性别:"+t.xb(sf));
}else {
System.out.println("输入有误重新输入");
}
;
}
**
代码三
**
String str = "abcd";
String str1 = "ABCD";
String str2 = " ABCD ";
String str3 = "123,4555,5678,9874,4";
// 下面所有方法都是返回新的字符串.str.toUpperCase()
// 转大写
System.out.println(str.toUpperCase());
// 转小写
System.out.println(str.toLowerCase());
// 判断是否以xx开头
System.out.println(str.startsWith("a",2));
// 判断是否以xx结尾
System.out.println(str.endsWith("F"));
// 忽略大小写内容比较内容
// 验证码
System.out.println(str.equalsIgnoreCase(str1));
// q去掉字符串前后空格
// 搜索
System.out.println(str2.trim());
// 根据指定字符分割,分割之后,分割条件是消失
String [] strings = str3.split(",");
for (String string : strings) {
System.out.println(string);
}
// 字符串替换
String str4 = "hello";
// str4.replace();都能用
System.out.println(str4.replaceAll("ello", "i"));
// 字符串和其他类型的转换
int i = 10;
// 任何数据类型和字符串类型做加法,结果都是字符串
// 阿里规约不允许用这个方法String s = i + "i";//" "空串可以指针,null空指针异常
String s = String.valueOf(i);
System.out.println(s);
// 字符串转数组
String str5 = "abcdef";
char [] array = str.toCharArray();
for (char c:array) {
System.out.println(c);
}
// 转字节型数组
// 一般用于文件
byte [] bytes = str.getBytes();
for (byte b:bytes) {
System.out.println(b);
包装器类型(包装类,封装类)基本数据类型转换成对应数据类型
-
int --------------------Integer
-
long ------------------Long
-
short -----------------Short
-
float ------------------Float
-
double ---------------Double
-
char ------------------Character
-
byte-------------------Byte
-
boolean -------------Boolean
包装器类型(包装类,封装类)
// int -------- Integer
// char -------- Character
// 其他6种基本一样子首字母大写
/*
* 为什么要有包装器类型?
原理:
* 装箱子把int包装成包装器Integer
* 基本数据类型转换成对应数据类型
* 拆箱:
* 拆箱时候把Integer类型转换成int 类型
* 包装器类型转换成对应的基本数据类型
* JDK5;
* */
Integer i1 = 20;
Integer i2 = Integer.valueOf(50);
int ii =i2;
int ii2 = i2.intValue();
/*
* JDK5之后的新功能
* 1.自动装箱和自动拆箱
* 2.增强for循环(foreach)
* 3.枚举
* JDK7以后的新功能
* switch.....case 可以用String
* */
String s ="1990";
Integer i = Integer.parseInt(s);
System.out.println(2022-1990);
面向对象编程三大特征
访问修饰符有哪些
基本介绍
面向对象编程有三大特征:封装、继承和多态。
String 字符串
-
String 是一个类
-
类中有哪些结构?
-
属性、方法、构造器
-
String 这个类是不是也有属性、方法、构造器?
-
常量不会存在于堆
.封装介绍
封装就是(encapsulation)就是把抽出的数据[属性]和对数据的操作[方法]封装子在一起,数据被保护在内部,程序的其他部分只有通过被授权的操作[方法],才能对数据进行操作。
封装的实现步骤 (三步)
继承介绍
类与类之间的关系
-
属性关系
-
参数关系
-
继承关系
1.1基类 subclass
Person、Cat、Animal可以叫做Biology类的子类
Animal叫做Biology类的直接子类
Person、Cat叫做Biology类的间接子类,Person、Cat是Animal的直接子类
1.2超类 superclass
Person、Cat直接父类是Animal,写在extends关键字后面的类
Person、Cat间接父类是Biology
继承给编程带来的便利
代码的复用性提高了
代码的扩展性和维护性提高了
extends 继承
在Java中,继承是单继承,一个子类只能有一个直接父类,但是可以有多个间接父类
注意:extends后面只能写一个类
2.2继承流程
创建子类对象时,父类先被实例化,再去实例化子类
当一个类被实例化时,一定会先实例化它的直接和间接父类
子类的构造器可以有多个,但是必须和父类的构造器形式上统一
2.3super关键字:
代表调用父类的结构(属性、方法、构造器)
2.4this和super的区别?
在子类中当使用super调用父类的构造器时,super(age)必须是第一句话
在当前类中使用this调用本类的构造器时,this(name)必须是第一句话
在构造器中,如果需要使用super或this调用其他构造器,只能二选一,而且还必须是第一句话
super指向的父类,不代表任何对象。
this指向的本类,代表当前类的对象,方法的调用者。
方法的重写
也可以说成覆写,覆盖,override
3.1什么是重写
子类可以重写父类的方法
我们可以利用到父类中方法已经运算过的结果,在结果的基础上进行扩展
体现的就是继承的核心,就是为了扩展父类的功能。
3.2方法的重写的规则
需要满足一个前提:继承与被继承的关系
访问权限:重写的方法的权限不能低于被重写的方法。开发中一般都是等于。
返回值类型:重写的方法的返回值可以和被重写的方法不同,但是必须是被重写方法的返回值的子类。开发中,一般就是一样。
方法名:必须相同
参数列表:参数类型,参数个数必须相同。
抛出异常:重写的方法不能抛出比被重写的方法更大的异常
final关键字 最终的,终极的
final可以修饰的结构:
1.类 public final class
最终类,终极类
2.属性 private final String name
final修饰的常量不能改变
常量的命名规则:单词的所有字母都大写,如果是多个单词,用下划线分割,不能只声明不赋值
3.方法 private final void show
不能被重写
方法的重写注解
@Override
我们建议在方法的重写处表明重写的注解
祖先类:Object (最顶级父类)
如果一个类没有明确的写出它的父类是谁,那它的父类就是Object
Object类中有11个方法:
1.hashCode( ):它的返回值实际上就是对象运行时的内存地址
hash算法:一般翻译“散列”,把任意长度的输入,通过一个散列的算法变换成固定长度的输出,输出结果
密码加密MD5加密
SHA家族
2.equals( ):和==没区别,比地址,为了让子类重写
Integer内部,有一个缓冲区,把byte范围内的数缓存起来了
3.toString( ):转换成字符串,当我们直接使用对象时,会默认调用toString方法,为了让子类重写
4.finalize( ):垃圾回收的方法
5.Clone( ):克隆,必须实现
多态
多态的形成有3个条件
1.有继承
2.有重写
3.有父类对象指向子类引用
多态形式
向上转型 父类 父类对象 = new 子类();
向下转型 要先发生向上转型,才能通过强转再转成子类类型
instanceof 关键字
判断第一个对象是否是某一个类的东西
if(animal instanceof Cat) {
Cat cat = new Cat();
cat.catchMouse();
}else if (animal instanceof Dog) {
Dog dog = new Dog();
dog.look();
} else {
code;
}
抽象
面向对象特征:抽象
Java中,除了类还有抽象类和接口
抽象方法:用抽象修饰的方法叫抽象方法
没有方法体(没有大括号)
抽象方法存在的意义是什么?
存在的意义是为了约定
根本意义,约定,自定义的规则
抽象方法到底约定了什么?(规定了什么?定了哪些规则?)
约定了返回值、访问权限、参数列表。需要在重写的时候去定义方法体
约定大于配置,配置大于编码
抽象方法必须在一个抽象类里
注意:
1.当我们定义一个抽象类,这个抽象类中可以有哪些结构?
属性、成员方法、构造器、抽象方法、常量
·定义常量
2.抽象类中能不能没有抽象方法?
抽象类可以没有抽象方法
3.抽象类是不能被实例化的(抽象类不能创建对象)
4.抽象类的构造器存在的意义
为了约定子类的构造器必须和父类要匹配
5.一个类如果继承了一个抽象类,就必须重写这个抽象类所有的抽象方法
abstract能修饰什么?
类和方法。
·抽象方法不能用private修饰,可以用public protected 默认的修饰
开发中,抽象方法基本上都是public
·抽象方法不能用final修饰。用final修饰的方法是不允许重写、不能被覆盖的。
·抽象类不能用final修饰。用final修饰的类是不允许被继承的。
总结:
1.抽象方法必须是public或protected或默认的(default)(因为如果是private是不能被子类继承的,子类便无法实现该方法)
2.抽象类不能被直接实例化,需要依靠子类采用向上转型的方法处理
3.抽象类必须有子类,使用extends继承
4.子类(前提:如果不是抽象类)则必须重写抽象类中的所有抽象方法(如果子类没有实现弗雷德抽象方法,必须将子类也定义为abstract)
抛出异常:
接口
比抽象类更高级的抽象
接口的声明:使用interface关键字
JDK7之前接口中只能定义抽象方法,不能有属性,不能有方法(也可以放静态常量和静态方法)
JDK8及以后:接口中只能定义抽象方法,不能有属性,可以有默认方法和静态方法、静态常量
图标发生变化
可以定义的方法
接口中结构的特点:
1.接口中的抽象方法默认是public abstract,我们推荐省略
2.接口中的常量默认是public static final,我们推荐省略
·接口中的结构必须是public
接口可以被一个类实现,这个类叫实现类
比如A类 implements 接口,那我们就说A是这个接口的实现类
如果一个类实现了一个接口,那它就需要重写接口中所有的抽象方法
实现接口是可以多实现的,但是继承只能单继承
用逗号隔开
在开发中,如果一件事情可以通过继承和实现接口来解决问题,优先选择使用接口解决
面试题:
1.继承抽象类和实现接口的异同。
·必须重写所有抽象方法
·继承抽象类是单继承,实现接口是多实现
2.抽象类和接口的区别。
·抽象类能放属性、普通成员方法、构造器等
·接口能放属性、成员方法、静态方法和默认方法
接口存在的意义?
约定
面向对象编程
面向接口编程(主要写接口)
1.写测试类
2.写sql语句
3.写实现类(写方法体)
面向切面编程
多态的前提条件
1.继承,实现
2.重写方法
3.父类指向子类,接口指向实现类
面试题:
在Java中只有单继承?
不对,有多继承。在Java中存在多继承,多继承发生在接口之间
Java类与类之间只有单继承
抽象类也是比类更高级的抽象
匿名对象
语法:new 类名();
功能:和正常有名字的对象的功能是相同的,依然具备了调用属性、方法的功能
使用场景:多数是用在传参、夹参,多数情况下配合构造器使用
好处:节约资源,栈的资源
数据结构
栈和队列:
栈和队列是两种操作受限的线性表
这种受限表现在:
栈的插入和删除只允许在表的尾端进行(在栈中叫做“栈顶”),满足FILO
First In Last Out
队列只允许在表尾插入元素,在表头删除元素:FIFO
First In First Out
栈与队列的相同点:
1.都是线性结构
2.插入操作都是在表尾进行
3.都可以通过顺序结构和链式结构实现
栈与队列的不同点:
1.队列是先进先出;栈是先进后出
总结:
1.抽象 abstract关键字
抽象类的特点
abstract能修饰哪些结构
抽象方法的特点
2.接口。JDK7-JDK8的有什么改变
3.面试题:继承类和实现接口的异同 抽象类和接口的区别
4.多态的补充说明
5.匿名实现类
重点:
结合多态,主要是参数的传递以及配合instanceof使用
在能够使用多态表示对象的时候,尽量使用多态
栈和队列
建立在两个最基础的数据结构的基础上构建的两个受限制的线性表
面向对象四大特征:
封装 继承 多态 (抽象)