根据b站的视频以及资料,整理了Java的基础知识。(第四章至第七章其余内容在第一周)
目录
第四章
1.抽象类和抽象方法
抽象方法:
使用abstract修饰的方法,没有方法体,只有声明。定义的是一种“规范”,就是告诉子类必须要给抽象方法提供具体的实现。
抽象类:
包含抽象方法的类是抽象类,通过abstract方法定义规范,然后要求子类必须定义具体实现,通过抽象类,我们就可以严格限制子类的设计,使子类之间更加通用。
要点:
1.有抽象方法的类只能定义成抽象类
2.抽象类不能的实例化,即不能用new来实例化抽象类
3.抽象类可以包含属性、方法、构造方法,但是构造方法不能用new实例,只能用来被子类调用
4.抽象类只能用来被继承
5.抽象方法必须被子类实现
public abstract class animal {
//没有实现,子类必须实现
abstract public void shout();
public static void main(String[] args) {
animal a=new dog();//new子类
a.shout();
}
}
class dog extends animal{
@Override
public void shout() {
System.out.print("汪汪!");
}
}
2.接口
接口是比“抽象类”还“抽象”的“抽象类”,可以更加规范的堆子类进行约束,全面的专业的实现了:规范和具体实现的分离
1.声明格式:【访问修饰符】 interface 接口名 【extends 父接口1,父接口2....】{
常量定义;
方法定义;
}
2.定义的详细说明:
1.访问修饰符:只能是public或默认
2.接口名:和类名采用相同的命名
3.extends:接口可以多继承
4.常量:接口中的属性只能是常量,总是:public static final 修饰
5.方法:接口中的方法只能是:public abstract
3.要点:1.子类通过implements来实现接口中的规范
2.接口不能创建实例,但是可以用于声明引用变量类型
3.一个类实现了接口,必须实现接口中所有的方法,并且这些方法只能是public的
public interface myinterface {
/*public abstract */void test01();
/*public static final */int a=100;
}
class myclass implements myinterface{
@Override
public void test01() {
System.out.print(a);
System.out.print("myclass.test01()");
}
}
public interface testinterface {
public static void main(String[]args) {
volant v=new angle();
v.fly();
//v.helpother();错误
angle a=new angle();
a.fly();
a.helpother();
honest o=new goodman();
o.helpother();
//o.fly();
}
}
interface volant{
void fly();
}
interface honest{
void helpother();
}
class angle implements volant,honest{
@Override
public void helpother() {
System.out.print("天使帮助你!");
}
@Override
public void fly() {
System.out.print("天使会飞!");
}
}
class goodman implements honest{
@Override
public void helpother() {
System.out.print("这个人很善良!");
}
}
多继承
public interface testinterface {
public static void main(String[]args) {
perfects f=new perfects();
f.test();
f.fly();
f.helpother();
}
}
interface volant{
void fly();
}
interface honest{
void helpother();
}
interface best extends volant,honest{//多继承
void test();
}
class perfects implements best{
@Override
public void fly() {
System.out.print("会飞!");
}
@Override
public void helpother() {
System.out.print("会帮助他人!");
}
@Override
public void test() {
System.out.print("很完美!");
}
}
3.内部类
1.成员内部类
可以使用private、default、protected、public任意进行修饰
分为非静态内部类,静态内部类
非静态内部类:
1.非静态内部类必须寄存在一个外部类对象里,因此,如果有一个非静态内部类对象那么一定存在对应的外部类对象,非静态内部类对象单独属于外部类的某个对象。
2.非静态内部类可以直接访问外部类的成员,但是外部类不能直接访问非静态内部类成员
3.非静态内部类不能有静态方法,静态属性和静态初始化块
4.外部类的静态方法,静态编码块不能直接访问非静态内部类,包括不能使用非静态内部类定义变量、创建实例
public class testinnerclass {
public static void main(String[]args) {
Outer.Inner inner=new Outer().new Inner();
inner.show();
}
}
class Outer{
private int age=10;
public void testOuter() {
System.out.println("Outer.testOuter()");
}
class Inner{//非静态内部类
int age=20;
public void show() {
int age=30;
System.out.println("外部类的成员变量age:"+Outer.this.age);
System.out.println("内部类的成员变量age:"+this.age);
System.out.println("局部变量age:"+age);
}
}
}
静态内部类:
1.定义方式:static class classname{ //类体}
2.当一个静态内部类对象存在,并不一定存在外部类对象,因此,静态内部类的实例方法不能直接访问外部类的实例方法
3.静态内部类看作外部类的一个静态成员,因此,外部类的方法中可以通过:“静态内部类.名字”的方式访问静态内部类的静态成员,通过new 静态内部类()访问静态内部类的实例
public class testinnerclass1 {
public static void main(String[]args) {
outer2.inner2 inner=new outer2.inner2();
inner.show();
outer2 outer=new outer2();
outer.outer2show();
}
}
class outer2{
static public int age=10;
static class inner2{
static int age=20;
public void show() {//内部类方法
int age=30;
System.out.println("外部类的成员变量age:"+outer2.age);
System.out.println("内部类的成员变量age:"+this.age);
System.out.println("内部类的成员变量age:"+age);
}
}
public void outer2show() {
System.out.println("外部类访问内部类的成员变量age:"+inner2.age);
}
}
2.匿名内部类
适合只需要使用一次的类
定义:new 父类构造器(实参类表)\实现接口(){ //匿名内部类类体 }
1.匿名内部类没有修饰符
2.匿名内部类没有构造方法
public class testanonymousInnerclass {
public static void test01(A a) {
a.aa();
}
public static void main(String[]args) {
testanonymousInnerclass.test01(new A() {//创建匿名内部类
@Override
public void aa() {
System.out.println("testanonymousInnerclass");
}
});
}
}
interface A{
void aa();
}
3.局部内部类
定义在方法内部,作用域只限于本方法
4.string类
1.string类又称作不可变字符序列
2.string位于Java.lang包中,Java程序默认导入Java.lang 包下的所有类
3.Java字符串是Unicode字符序列
4.Java没有内置的字符串类型,而是在标准Java类库中提供了一个预定义的类String,每个用双引号括起来的字符串都是String类的一个实例
public class teststring {
public static void main(String[]args) {
String str1="abc";
String str2=new String("def");
String str3="abe"+"def";
String str4="18"+19;//字符串连接符
System.out.println(str1);//abc
System.out.println(str2);//def
System.out.println(str3);//abedef
System.out.println(str4);//1819
}
}
常量池
通常比较字符串时,使用equals
如:System.out.println(str1.equals(str2));//true
String 类的使用方法
public class teststring2 {
public static void main(String[]args) {
String a1="core Java";
String a2="Core java";
System.out.println(a1.charAt(3));//提取下标为3的字符
System.out.println(a1.length());//输出字符串长度
System.out.println(a1.equalsIgnoreCase(a2));//忽略大小写比较字符串
System.out.println(a2.indexOf("java"));//判断s2中是否包含java,只返回第一个java的元素下标
System.out.println(a2.indexOf("hello"));//判断s2中是否包含hello,返回-1
String a=a1.replace(' ', '&');//将s1中的空格替换成&
System.out.println(a);
String s = "";
String s1 = "How are you?";
System.out.println(s1.startsWith("How"));//是否以How开头
System.out.println(s1.endsWith("you"));//是否以you结尾
s = s1.substring(4);//提取子字符串:从下标为4的开始到字符串结尾为止
System.out.println(s);
s = s1.substring(4, 7);//提取子字符串:下标[4, 7) 不包括7
System.out.println(s);
s = s1.toLowerCase();//转小写
System.out.println(s);
s = s1.toUpperCase();//转大写
System.out.println(s);
String s2 = " How old are you!! ";
s = s2.trim();//去除字符串首尾的空格。注意:中间的空格不能去除
System.out.println(s);
System.out.println(s2);//因为String是不可变字符串,所以s2不变
}
}
第七章
1.数组的拷贝
System类里包含了static void arraycopy(object src,int srcpos,object dest, int destpos,int length)方法,该方法可以将src数组里的元素值赋给dest数组的元素,其中srcpos指定从src数组的第几个元素开始赋值,length参数指定将src数组的多少个元素赋给dest数组的元素。
package a;
public class testarraycopy {
public static void main(String[]args) {
test();
test1();
String[]a= {"张三","李四","王五","赵六","小明"};
test2(a,2);//删掉王五
test3();
}
public static void test(){
String[]s1={"aa","bb","cc","dd","ee"};
String[]s2=new String[10];
System.arraycopy( s1,2,s2,6,3);
for(int i=0;i<s2.length;i++)
System.out.println(i+" "+s2[i]);
}
//测试从数组中删除一个数据
public static void test1(){
String[]s1={"aa","bb","cc","dd","ee"};
System.arraycopy( s1,3,s1,2,2);
s1[s1.length-1]=null;
for(int i=0;i<s1.length;i++)
System.out.println(i+" "+s1[i]);
}
//删除数组中指定索引位置的元素,并将原数组返回
public static void test2(String[]s,int index){
System.arraycopy( s,index+1,s,index,s.length-index-1);
s[s.length-1]=null;
for(int i=0;i<s.length;i++)
System.out.println(i+" "+s[i]);
}
//数组的扩容(本质上是先定义一个更大的数组,然后原封不动拷贝到新数组中)
public static void test3() {
String[]s1= {"aa","bb","cc"};
String[]s2=new String[s1.length+10];
System.arraycopy(s1, 0, s2, 0, s1.length);
for(int i=0;i<s2.length;i++)
System.out.println(i+" "+s2[i]);
}
}
2.arrays工具栏类的使用
import java.util.Arrays;
public class testarrays {
public static void main(String[]args) {
int[]a= {3,7,4,89,100,34,56};
System.out.println(a);//输出地址
System.out.println(Arrays.toString(a));//输出a内的元素
Arrays.sort(a);//排序
System.out.println(Arrays.toString(a));
System.out.println(Arrays.binarySearch(a, 100));//返回索引
System.out.println(Arrays.binarySearch(a, 50));//返回负数
}
}
3.多维数组
public class testdimensionArray {
public static void main(String[]args) {
int[][]b=new int[3][];
b[0]=new int[] {10,20};
b[1]=new int[] {10,20,30};
b[2]=new int[] {10,50,100,60};
System.out.println(b[2][2]);//100
//静态初始化二维数组
int[][]c= {
{20,30},
{40,90,60},
{100,455,54,245}
};
System.out.println(c[2][3]);//245
}
}
4.多维数组存储表格数据
表格数据模型是计算机世界最普遍的模型,可以这么说,大家在互联网上看到的所有数据本质上都是“表格”,无非是表格之间互相套用
import java.util.Arrays;
public class testArrraytabledata {
public static void main(String[]args) {
Object[]emp1= {0001,"喜羊羊",8,"羊村","2000.1.1"};
Object[]emp2= {0001,"灰太狼",10,"狼堡","2021.2.2"};
Object[]emp3= {0001,"熊大",13,"狗熊岭","2008.8.4"};
Object[][]tabledata=new Object[3][];
tabledata[0]=emp1;
tabledata[1]=emp2;
tabledata[2]=emp3;
for(Object[] temp:tabledata) {
System.out.println(Arrays.toString(temp));
}
}
}
JAVA编译器会自动把基本数据类型“自动装箱”成包装类对象。大家在下一章学了包装类后就懂了。
5.冒泡排序
冒泡排序算法的运作如下:
1. 比较相邻的元素。如果第一个比第二个大,就交换他们两个
2. 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的
3. 针对所有的元素重复以上的步骤,除了最后一个
4. 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较
import java.util.Arrays;
public class testbubblesort {
public static void main(String[]args) {
int[] value= {6,8,2,1,5,7,4,3};
int temp=0;
for(int i=0;i<value.length-1;i++) {
boolean flag=true;
for(int j=0;j<value.length-1-i;j++) {
if(value[j]>value[j+1]) {
temp=value[j];
value[j]=value[j+1];
value[j+1]=temp;
flag=false;//即如果不发生交换
}
}
if(flag) {
break;//优化了
}
System.out.println(Arrays.toString(value));
}
}
}
6.二分法查找
二分法检索又称折半检索,二分法检索的基本思想是设数组中的元素从小到大有序地存放在数组中,首先将给定值key与数组中间位置上元素的关键码(key)比较,如果相等,则检索成功;否则,若key小,则在数组前半部分中继续进行二分法检索;若key大,则在数组后半部分中继续进行二分法检索。这样,经过一次比较就缩小一半的检索区间,如此进行下去,直到检索成功或检索失败。二分法检索是一种效率较高的检索方法。
import java.util.Arrays;
public class testbinarysearch {
public static void main(String[]args) {
int[]arr= {30,20,60,80,90,120,25,46,79,37,135};
Arrays.sort(arr);//排序
System.out.println(Arrays.toString(arr));
System.out.println(test(arr,100));
}
public static int test(int[]arr,int value) {
int low=0;//最小的索引
int hight=arr.length;//最大的索引
while(low<=hight) {
int mid=(low+hight)/2;//中间的索引
if(value==arr[mid]) {
return mid;
}
else if(value>arr[mid]) {
low=mid+1;
}
else if(value<arr[mid]) {
hight=mid-1;
}
}
return -1;//如果arr中不包含此数,返回-1
}
}