Java之路 - String类、static、继承、覆盖重写、super
1.String类
字符串是常量,他们的值在创建后不可更改!!!
正是因为字符串不可改变,所以字符串是可以共享使用的
字符串效果上相当于是char【】字符数组,但是底层原理是byte【】字节数组
常见的创造方法:3+1种 三种构造方法、一种直接创建
(1)public String();
(2)public String(char【】 array);根据字符数组的内容,来创建对应的字符串。
(3)public String(byte【】array);根据字节数组的内容来创建对应的字符串。
四种创建方法:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public class DemoString { public static void main(String[] args) { //根据字符数组创建字符串 char[] chararray = {'A','B','C'}; String str1 = new String(chararray); System.out.println(str1); //根据字节数组创建字符串 byte[] bytearray = { 97 , 98 , 99}; String str2 = new String(bytearray); System.out.println(str2); //直接创建 String str3 = "hello, i am chris"; System.out.println(str3); } } 第一种创建空字符串的省略了
2.字符串的常量池
现象:
String str1 = "abc"; String str2 = "abc"; char[] charArray = {'a', 'b','c'}; String str3 = new String(charArray); System.out.println(str1 == str2); //true System.out.println(str1 == str3); //false System.out.println(str2 == str3); //false
字符串常量池:程序当中直接写上的双引号字符串,就在字符串常量池中。new的不在池当中
对于基本数据类型来说 == 是进行数值的比较
对于引用类型来说 == 是进行地址值的比较
示意图解释:
对于str1和st2,他们两指向的都是字符串常量池中所对应的同一个底层实现的字节数组,所以地址值相同。
而对于str3来说,它不是new出来的,所以不在常量池当中,内部实现是将字符数组转换为字节数组,是新的一个对象,新的地址值。
3.字符串的比较方法
(1) public boolean equals(Object obj);参数可以是任何对象,任何对象都可以用Object接收; 判断两个字符串内容是否一致;
public class StringMethod { public static void main(String[] args) { String str1 = "hello"; char[] charArray = {'h','e','l','l','o'}; String str2 = new String(charArray); System.out.println(str1.equals(str2)); } }
如果比较双方是一个常量和一个变量,推荐把常量字符串写在前面
当String str1= null;时, 如果这么写 str1.equals(“abc”) 会报错,因为str1为空指针
(2)public boolean equalsIgnoreCase(String str);忽略大小写,进行内容比较;
4.字符串的length、concat、charAt、indexOf方法
public int length():获取字符串当中含有的字符个数
public String concat(String str):将当前字符串和参数字符串进行拼接,返回值为新的字符串
public char charAt(int index):获取指定索引位置的单个字符
public int indexOf(String str):查找参数字符串在本字符串当中首次出现的索引位置,如果没有就返回-1值
5.字符串的截取方法 - - public String substring(int begin,int end) 左闭右开区间
System.out.println(str2.length()); System.out.println(str2.charAt(2)); System.out.println(str2.concat("dss")); System.out.println(str2.indexOf('e')); System.out.println(str2.substring(2,5));
6.字符串相关的转换方法 - - toCharArray、getBytes、replace
(1)public char【】 toCharArray():将当前字符串拆分成字符数组作为返回值
(2)public byte【】 getBytes():获取当前字符底层的字节数组
(3)public String replace(CharSequence oldString,CharSequence newString):将所有出现的老的字符串替换为新的样子
CharSequence意思就是说可以接受字符串类型,是一个接口
7.字符串切割方法 - - - public String【】 split(String regex) 按照参数的规则,将字符串切割成若干个部分
String str3 = "aaa,bbb,ccc";
String[] result = str3.split(",");
注意事项:spilt的参数采用的是正则表达式的查询方法!!
字符串拼接练习1:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public class StringMethod { public static void main(String[] args) { int[] array1 = {1, 2, 3}; String result = arrraymethod(array1); System.out.println(result); } public static String arrraymethod(int[] array) { String result = "["; for (int i = 0; i < array.length; i++) { if (i == array.length - 1) { result += "word" + array[i] + "]"; } else { result += "word" + array[i] + "#"; } } return result; } }
字符串统计练习2:统计出键盘输入的字符串中大写字母、小写字母、数字、其它字符的个数
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public class StringPractise { public static void main(String[] args) { Scanner s1 = new Scanner(System.in); System.out.println("请输入一个字符串:"); String str = s1.next(); //获取键盘输入的字符串 //创建四个计数器 int countUpper = 0; int countLower = 0; int countNum = 0; int countOther = 0; //将字符串转换为字符数组 char[] StringArray = str.toCharArray(); for (int i = 0; i < StringArray.length; i++) { char charnow = StringArray[i]; //charnow表示的是遍历的当前字符 if ('A' <= charnow && charnow <= 'Z'){ //因为字符类型在做数学运算时为自动提升为int类型 所以可以进行比较 countUpper++; }else if('a' <= charnow && charnow <= 'z'){ countLower++; }else if('0' <= charnow && charnow <= '9'){ countNum++; }else { countOther++; } } System.out.println("大写字母有:" + countUpper +"个"); System.out.println("小写字母有:" + countLower + "个"); System.out.println("数字有:" + countNum + "个"); System.out.println("其他字符有:" + countOther + "个"); } }
8.static关键字
static属于类,共享给对象
用于学生类:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package basicpart.day01; public class Student{ private String name; private int age; private int id = 0; static String classroom = "七六班"; private static int idCounter = 0;//学号计数器 每当有一个对象产生,计数器++ 外部不可访问 public Student() { } public Student(String name, int age) { this.name = name; this.age = age; this.id = ++idCounter; } 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 int getId() { return id; } public void setId(int id) { this.id = id; } }
如果修饰方法的话,那么这个方法就变成了静态方法,属于类,可以通过对象名调用,但不推荐,也可以直接通过类名称来调用,推荐
无论是成员变量还是成员方法,只要被static修饰,都推荐用类名称来调用
静态方法不能直接访问非静态 - - 因为内存当中是先有的静态内容,后有的非静态内容 “先人不知道后人,但后人知道先人”
静态方法当中不能用this,因为访问静态方法是推荐类来用,而不是对象,不存在对象
static内存显示:
静态代码块:格式:static{ } 加个大括号 只执行一次!!!! 用途:用来一次性地对静态成员变量进行赋值
当第一次用到本类时,静态代码块执行唯一的一次 静态内容总是优先于非静态 所以创建对象时 先执行静态代码块 再执行构造方法
9.Arrays - - 与数组相关的工具类、里面包括了大量的静态方法
(1)public static String toString(数组) - - - 将参数数组变成字符串(按照默认格式[元素1,元素2,元素3...])
(2)public static void sort(数组) - - - 按照默认升序对数组的元素进行排序 没有返回值 如果是字符串 按照字母升序
如果是自定义类型,那么这个自定义的类要有Comparable或者Comparator接口的支持
练习:将一个随机字符串中的所有字符进行升序排列,并倒序打印
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public class FaceObject { public static void main(String[] args) { String str1 = "asgewf2124sa14dsg"; char[] charArray = str1.toCharArray(); // 先将字符串变为字符数组 Arrays.sort(charArray); // 对字符数组进行升序排列 for (int i = charArray.length-1; i >= 0; i--) { //倒序遍历 forr就是倒序 System.out.println(charArray[i]); } } }
10.数学工具类 - Math
(1)public static double abs(double num) - - - 获取绝对值
(2)public static double ceil(double num) - - - 向上去整 12.1变13
(3)public static double floor(double num)- - - 向下取整
(4)public static long round(double num)- - - 四舍五入
有个常量 Math.PI代表近似的圆周率
练习:计算在-10.8 到 5.9之间,绝对值大于6或者小于2.1的整数有几个
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public class FaceObject { public static void main(String[] args) { double min = - 10.8; double max = 5.9; int absCount = 0; //这样处理,就是区间之内所有的整数 for(int i = (int) min; i < max; i++){ int abs = Math.abs(i); //取绝对值 if (abs > 6 || abs < 2.1){ System.out.println(i); absCount++; } } System.out.println("总共有" + absCount +"个"); } }
11.继承
父类:也可以叫基类、超类;
子类:public clas 子类名称 extends 父类名称;
当三个变量重名时,super关键字为父类成员变量,this为子类成员变量,局部变量可直接打印;如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
父类: public class Fu { int num = 10; } 子类: public class Zi extends Fu{ int num = 20; public void ziMethod(){ int num = 30; System.out.println(num); //输出的是局部变量num = 30 System.out.println(this.num); //输出的是成员变量 num = 20 System.out.println(super.num); //输出的是父类的成员变量 num = 10 } } 调用: public class MainMethod { public static void main(String[] args) { Zi zi = new Zi(); zi.ziMethod(); } }
12. 方法的重写(Override)或者叫覆盖重写、覆写:
(1)在继承关系当中,方法的名称一样,参数列表也一样;可以用@Override来监测
(2)子类方法的返回值必须小于或等于父类方法的返回值范围; Object大于一切
(3)子类方法的权限必须大于等于父类方法的权限修饰符; public > protected > (default) > private
备注:(default)不是关键字default 而是什么都不写 留空
@Override public void method() { super.method(); }
继承关系中,父子类构造方法的访问特点:
1.子类构造方法当中有一个默认隐含的super()调用(系统赠送),所以一定是先调用的父类构造方法,再执行的子类构造方法 !!!必须调用父类的一个构造方法
2.可以通过super关键字在子类构造调用父类重载构造
public Zi(){ super(12); System.out.println("子类无参构造"); }
3.super的父类构造调用,必须是子类构造方法的第一个语句,不能一个子类构造调用多次super构造
13.super关键字的三种用法
1.在子类的方法中,访问父类的成员变量
2.在子类的成员方法中,访问父类的成员方法
3.在子类的构造方法中,访问父类的构造方法
14.this关键字的三种用法
super关键字用来访问父类内容,而this关键字用来访问本类内容
1.在本类的成员方法中,访问本类的成员变量
2.在本类的成员方法中,访问本类的另一个成员方法
3.在本类的构造方法中,访问本类的另一个构造方法
public Zi(){ this(12); System.out.println("子类无参构造"); } public Zi(int num){ System.out.println("子类有参构造"); }
注意:this(...)调用也必须是构造方法的第一个语句 super和this 两种构造调用不能同时使用
this,super内存演化过程: