Java基础 数据类型 java中有八种数据类型
byte
short
int
long
float
double
String
char
类型转换 数据类型的转换分为两种:强制转换和自动转换
自动转换 :例如:int转换为double ,java中规定好的,由低到高的转换,不需要强制执行,java的源码中已经设定好。
强制转换 :例如:
1 2 3 int a = 125 ;byte b = byte (a);
如上,一个int类型的变量被强制转换为byte类型,这是由高到低,因此需要强制转换,即在被转换的变量前加转换后的数据类型。
注意 :强制数据类型转换存在一个和严重的问题,即内存溢出
1 2 int a = 128 ; byte b = byte (a);
变量、常量、作用域 变量 :指的是在内存中的一个空间,可以放你想放的任何东西,由于不确定性所以取名变量。
常量 :用final修饰的一个固定的值,其中变量的名字需要大写 。
作用域 :
类的作用域
static 修饰类的全局作用域,不论是前置还是后置都一样。
实例变量作用域 String name = “李四”;
方法的作用域
main方法里面定义的变量
自增和自减 a++ :先自增,后赋值
++a :先赋值,后自增
逻辑运算、位运算 && : 两个都为真,结果才是真
|| :有真即真
!:取反
<<
左移,乘以2
》》
右移,除以2
^
幂
三元运算 1 2 double a = 80 ;double b = a < 60 ? "及格" :"不及格" ;
Sanner类
导入Scanner类
new出Scanner
变量接受输入
关闭Scanner
next():以空格结束
hasnext():以Enter键结束
判断输入的数据类型方法:
hasNextInt():判断输入的数据是否是int类型
hasNextfloat():判断输入的数据是否是float类型
顺序结构 java的基本结构就是顺序结构,除非特别申明,否则一定是一行一行执行,同时顺序结构也是最简单的算法结构。
if选择结构
1 2 3 4 5 6 7 8 9 10 11 if (布尔表达式){ }else if (布尔表达式1 ) { }else if (布尔表达式2 ){ }else { }
1 2 3 4 5 6 7 if (布尔表达式1 ){ if (布尔表达式2 ){ } }
Switch选择结构 多选择结构 switch case,switch中的变量类型可以是:byte 、short、int、char、String(JavaSE7)
1 2 3 4 5 6 7 8 9 10 11 12 switch (expression){ case value: break ; case value : break ; default : break ; }
While循环结构
只要布尔表达式为true,则一直循环
大多数情况会设置表达式让循环停止
尽量避免死循环
例子:输出1+2+3+4+5+….+100
1 2 3 4 5 6 7 i=0 ; sum = 0 ;while (i<=100 ){ sum = sum + i; i++; Sys.out(i); }
DoWhile循环结构 do…while循环至少会进入循环一次
与while的区别 :
while先判断后执行,dowhile是先执行再判断
dowhile至少会执行一次
For循环结构
注意 :最先执行的初始化步骤,可以声明一种类型,但可初始化一个或者多个循环控制变量,也可以是空语句。
然后,检测布尔表达式的值。如果为true,循环体继续,如果为false,循环终止,开始执行循环体后面的语句。
执行一次循环体以后,更新循环体控制变量。
打印九九乘法表 1 2 3 4 5 6 7 8 9 public static void main (String[] args) { for (int j = 1 ; j <= 9 ; j++) { for (int i = 1 ; i <= j; i++) { System.out.print(j+"*" +i+"=" +(j*i) + "\t" ); } System.out.println(); } }
先写一个for循环,实现第一列
1 2 3 4 5 6 public static void main (String[] args) { for (int i = 1 ; i <= 9 ; i++){ System.out.println(i+"*" +i+"=" +(1 *i)); } }
1 2 3 4 5 6 7 8 9 1 *1 =1 1 *2 =2 1 *3 =3 1 *4 =4 1 *5 =5 1 *6 =6 1 *7 =7 1 *8 =8 1 *9 =9
再写一个for循环包裹上一个for循环
1 2 3 4 5 6 7 public static void main (String[] args) { for (int j = 1 ; j <= 9 ; j++) { for (int i = 1 ; i <= 9 ; i++) { System.out.println(1 +"*" +i+"=" +(1 *i)); } }
注意 :此时已经能够输出乘法表,但是有多余的部分,需要去重,即把 1 换成 j
1 2 3 4 5 6 7 public static void main (String[] args) { for (int j = 1 ; j <= 9 ; j++) { for (int i = 1 ; i <= j; i++) { System.out.println(j+"*" +i+"=" +(j*i)); }
此时乘法表已经完成,剩下就是排版,即再输出后面加“\t” 以及 换行即可
1 2 3 4 5 6 7 8 public static void main (String[] args) { for (int j = 1 ; j <= 9 ; j++) { for (int i = 1 ; i <= j; i++) { System.out.print(j+"*" +i+"=" +(j*i)+"\t" ); } System.out.println(); }
增强For循环 1 2 3 4 5 6 public static void main (String[] args) { int [] numbers = {10 ,20 ,30 ,40 ,50 }; for (int i :numbers){ System.out.println(i); } }
break、continue、goto break: 循环的主体部分, 强制退出循环
continue:用于终止某一次循环
goto:保留字,类似前端的锚点
方法的定义和调用 方法:语句的集合,即函数。
1 2 3 4 5 6 7 8 main(){ int c = add(1 ,2 ); Sys.out(c) }public static int add (int a ,int b) { return a+b; }
方法的格式: 修饰符 返回值类型 方法名 (参数类型,参数名 ){
。。。
方法体
。。。
return 返回值;
}
方法的调用
类一 实现方法
1 2 3 4 public static void sayHello () { System.out.println("Hello" ); return ; }
类二 可以直接调用
1 2 3 public static void main (String[] args) { sayHello(); }
第二种情况 :方法a可以直接调用方法b
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public class Demo02 { public void a () { b(); } public void b () { } }public class Demo02 { public static void a () { b(); } public static void b () { } }
注意 :以下情况会报错,原因是static方法与类同时加载,此时b还没有创建,无法调用
1 2 3 4 5 6 7 public class Demo02 { public static void a () { b(); } public void b () { } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 public static void main (String[] args) { Demo02 demo = new Demo02 (); demo.a(1 ,2 ); } public int a (int a,int b) { return a + b; } public static void b () { }public static void main (String[] args) { Demo.a(1 ,2 ); } public static int a (int a,int b) { return a + b; } public static void b () { }
类一 非静态方法,无法夸类调用,可以实例化这个类,即new 一个类调用方法。
1 2 3 4 public void sayHello () { System.out.println("Hello" ); return ; }
类二
1 2 3 4 5 6 7 8 9 10 11 public static void main (String[] args) { new 类名().方法() new Student ().sayHello(); Student student = new Student () student.sayHello(); sayHello(); }
实参与形参数的类型要一致
值传递与引用传递 值传递
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 public class Demo02 { public static void main (String[] args) { int a= 1 ; System.out.println(a); Demo02.change(a); System.out.println(a); } public static void change (int a) { a=10 ; } } Picked up _JAVA_OPTIONS: -Dawt.useSystemAAFontSettings=on -Dswing.aatext=true 1 1 Process finished with exit code 0
引用传递
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 public class Demo02 { public static void main (String[] args) { Student student = new Student (); System.out.println(student.name); Demo02.change(student); System.out.println(student.name); } public static void change (Student student) { student.name = "Student" ; } }class Student { String name; }
方法的重载 重载就是在同一个类中,有相同的函数名称,但是行参不同的函数。
规则 :
方法的名称必须相同。
参数列表必须不同(个数不同、或类型不同、参数排列顺序不同等)。
方法的返回类型可以相同也可以不同
仅仅返回类型不同不能够称为方法的重载
可变参数
JDK1.5开始,java支持传递同类型的可变参数给一个方法。
在方法声明中,在指定参数类型后面加一个省略号(…)。
一个方法中只能指定一个可变参数,它必须是方法的最后一个参数。任何普通的参数必须在它之前声明。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 public static void printMax ( double ...numbers) { if (numbers.length == 0 ){ System.out.println("No argument passed" ); return ; } double result = numbers[0 ]; for (int i = 1 ; i<numbers.length;i++){ if (numbers[i]>result){ result = numbers[i]; } } System.out.println("The max value is " + result); }
递归讲解 递归:A方法调用A方法!就是自己调用自己
结构 :
递归头:什么时候不调用自身方法。如果没有头,将陷入死循环。
递归体:什么时候需要调用自身方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 public static void main (String[] args) { System.out.println(f(10 )); }public static double f (double n ) { if (n == 1 ) { return 1 ; }else { return n*f(n-1 ); } }
数组
相同类型数据的有序集合。
相同类型的若干个数据,按照一定的先后顺序排列组合而成。
其中,每一个数据称作一个数组元素,每个数组元素可以通过一个下标来访问它们。
数组的声明与创建
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 public static void main (String[] args) { int [] nums ; nums = new int [10 ]; double [] ds = new double [10 ]; nums[0 ] = 0 ; nums[1 ] = 1 ; nums[2 ] = 2 ; nums[3 ] = 3 ; nums[4 ] = 4 ; nums[5 ] = 5 ; nums[6 ] = 6 ; nums[7 ] = 7 ; nums[8 ] = 8 ; nums[9 ] = 9 ; int sum = 0 ; for (int i = 0 ; i < nums.length; i++) { sum += nums[i]; System.out.println(sum); } }
特点 :
数组的长度是确定的,数组一旦被创建,其大小就是不可以改变的。
其元素必须是同类型,不允许出现混合类型。
数组中的元素可以是任何数据类型,包括基本的数据类型和引用数据类型。
数组变量属于引用类型,数组也可以看成是对象,数组中的每一个元素相当于该对象的成员变量。
数组的本身就是对象,java中对象是在堆中的,因此数组无论保存原始数据类型还是其他对象类型,数组对象本身是在堆中的
三种初始化以及内存分析 1 2 3 4 5 6 7 8 9 10 public static void main (String[] args) { int [] a = { 0 ,1 ,2 ,3 ,4 ,5 }; int [] b = new int [10 ]; b[0 ] = 10 ; }
下标越界 超出数组长度,会报错(下标越界)
数组的使用 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 public static void main (String[] args) { int [] array = { 1 ,2 ,3 ,4 ,5 ,6 ,7 ,8 ,9 ,10 }; for (int i = 0 ; i < array.length; i++) { System.out.println(i); } int sum = 0 ; for (int i = 0 ; i < array.length; i++) { sum += array[i]; System.out.println("求和结果是" +sum); } int max = array[1 ]; for (int i = 1 ; i < array.length; i++) { if (array[i]>max) { max = array[i]; } }
二维数组 :
1 2 3 4 5 public static void main (String[] args) { int [][] a = {{0 ,1 }}; System.out.println(a[0 ][0 ]); }
Arrays类 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 public static void main (String[] args) { int [] array = {1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 }; int [] b = new int [10 ]; System.out.println(array); System.out.println(Arrays.toString(array)); Arrays.sort(array); System.out.println(Arrays.toString(array)) ; Arrays.fill(b,2 ,4 ,1 ); System.out.println(Arrays.toString(b)); } public static void h (int [] array) { for (int i = 0 ; i < array.length; i++) { if (i == 0 ) { } System.out.println(Arrays.toString(array)); } }
冒泡排序 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 public static void main (String[] args) { int [] a = {1 ,4 ,5 ,62 ,24 ,56 ,35 ,99 ,2 ,35 ,563 ,9 }; int [] sort = sort(a); System.out.println(Arrays.toString(sort)); } public static int [] sort(int [] array){ int temp = 0 ; for (int i = 0 ; i < array.length-1 ; i++) { boolean flag = false ; for (int j = 0 ; j <array.length-1 -i; j++){ if (array[j+1 ]<array[j]){ temp = array[j]; array[j] =array[j+1 ]; array[j+1 ] =temp; flag = true ; } } if (flag== false ) { break ; } } return array; }
稀疏数组
我真牛逼,这都写出来了,自己写的自己都看不懂了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 public class Demo01 { public static void main (String[] args) { int [][] array1 = new int [11 ][11 ]; array1[1 ][2 ] = 1 ; array1[2 ][3 ] = 2 ; System.out.println("输出原始的数组" ); for (int [] ints : array1) { for (int anInt: ints) { System.out.print(anInt+"\t" ); } System.out.println(); } System.out.println("================================================" ); int sum = 0 ; for (int i = 0 ; i < 11 ; i++) { for (int j = 0 ; j < 11 ; j++) { if (array1[i][j] != 0 ) { sum++; } } } System.out.println("有效值的个数:" + sum); int [][] array2 = new int [sum+1 ][3 ]; array2[0 ][0 ] = 11 ; array2[0 ][1 ] = 11 ; array2[0 ][2 ] = sum; int count = 0 ; for (int i = 0 ; i < array1.length; i++) { for (int j = 0 ; j < array1[i].length; j++) { if (array1[i][j] != 0 ) { count++; array2[count][0 ] = i; array2[count][1 ] = j; array2[count][2 ] = array1[i][j]; } } } System.out.println("稀疏数组" ); for (int i = 0 ; i < array2.length; i++){ System.out.println(array2[i][0 ]+"\t" +array2[i][1 ] + "\t" +array2[i][2 ] + "\t" ); } System.out.println("================================================" ); System.out.println("还原" ); int [][] array3 = new int [array2[0 ][0 ]][array2[0 ][1 ]]; for (int i=1 ; i<array2.length; i++){ array3[array2[i][0 ]][array2[i][1 ]] = array2[i][2 ]; } System.out.println("输出原始的数组" ); for (int [] ints : array3) { for (int anInt: ints) { System.out.print(anInt+"\t" ); } System.out.println(); } } }
面向对象 面向过程思想 :
步骤清晰简单,第一步做什么,第二步做什么……
面对过程适合处理一些较为简单的问题
面向对象思想 :
物以类聚,分类的思维模式,思考问题首先会解决问题需要哪些分类,然后对这些分类进行单独思考。最后,才对某个分类下的细节进行面对过程的思索。
面对对象适合处理复杂的问题,适合处理需要多人协作的问题!
对于描述复杂的事物,为了从宏观上把握、从整体上合理分析,我们需要使用面象对象的思路来分析整个系统。但是,具体到微观操作,仍然需要面向过程的思路去处理。
面向对象编程 :
以类的方式组织代码,以对象的组织(封装)数据。
抽象
三大特性:
封装
继承
多态
类与对象 终于搞明白了这个玩意[苦涩][苦涩]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 public class Demo02 { public static void main (String[] args) { Student student1 = new Student (); Student student2 = new Student (); student1.name = "xiaoming" ; student1.age =15 ; System.out.println(student1.name); System.out.println(student1.age); System.out.println("================================================================" ); System.out.println(student2.name); System.out.println(student2.age); } }class Student { String name; int age; public void change () { System.out.println("Student" ); } } xiaoming15 ================================================================null 0
构造器
一个类即使什么都不写,只要被创建了就有一个默认的方法,即构造方法。
1.必须和类的名字相同
2.必须没有返回类型,也不能写void
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 public class Demo02 { public static void main (String[] args) { Student student = new Student (); System.out.println(student.name); } }class Student { String name; public Student () { } public Student (String name) { this .name = name; } }
构造器 :
作用 :
注意点 :
定义参数构造后,如果想使用无参构造,显示的定义一个无参的构造
类与对象的小结
类与对象
类是一个模板:抽象,对象是一个具体的实例
方法
定义与调用
对象的引用
引用类型: 基本类型(8)
对象是通过引用来操作的:栈—->堆
属性:字段Filed 成员变量
默认初始化:
数字:0 0.0
char : u0000
boolean : false
引用: null
修饰符 属性类型 属性名 = 属性值!
对象的创建和使用
必须使用new 关键字创造对象,构造器 Student student = new Student();
对象的属性 student.name
对象的方法 student.say();
类:
静态的属性 属性
动态的方法 方法
封装
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 package com.woniu;public class Demo02 { public static void main (String[] args) { Student student = new Student (); student.setName("Student" ); System.out.println(student.getName()); } }class Student { private String name; private int age; private int id; private String email; public Student () { this .name = name; this .age = age; this .id = id; this .email = email; } public Student () { this .name = name; this .age = age; this .id = id; this .email = email; } public String getName () { return name; } public void setName (String name) { this .name = name; } public int getAge () { if (age<20 || age >100 ){ age = 18 ; }else { this .age = age; } return age; } public void setAge (int age) { this .age = age; } public int getId () { return id; } public void setId (int id) { this .id = id; } public String getEmail () { return email; } public void setEmail (String email) { this .email = email; } }
特点 :
提高程序的安全性,保护数据
隐藏代码的实现细节
统一接口
系统可维护增加了
继承
继承的本质是对某一批类的抽象,从而实现对现实世界更好的建模。
extends的意思是“扩展”。子类是父类的扩展
java中只有单继承,没有多继承!
继承是类与类之间的一种关系。除此之外,类和类之间的关系还有依赖、组合、聚合等。
继承关系的两个类,一个为子类(派生类),一个是父类(基类)。子类继承父类,使用关键字extends来表示。
子类与父类之间,从意义上讲应该具有“is a”的关系。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 public class Demo02 { public static void main (String[] args) { Student student = new Student (); student.say(); } }class Student extends Person { }class Person { public void say () { System.out.println("Hello " ); } }class Teacher { }
Supper 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 public class Demo02 { public static void main (String[] args) { Student student = new Student (); } }class Student extends Person { private String name = "Student" ; public Student () { super (); System.out.println("子类无参" ); } public void say1 () { System.out.println("Hello,world!" ); } public void test (String name) { System.out.println(name); System.out.println(this .name); System.out.println(super .name); } public void test1 () { say1(); this .say1(); super .say(); } }class Person { public Person () { System.out.println("父类无参" ); } protected String name = "Johnny" ; public void say () { System.out.println("Hello " ); } }class Teacher { }
supper注意点:
supper调用父类的构造方法,必须在构造方法中的地一个
supper 必须只能出现在子类的方法中或者构造方法中
supper 和 this 不能同时调用构造方法
Vs this :
this : 本身调用者这个对象
supper: 代表父类对象的应用
前提
this:没有继承也可以使用
supper:只能在继承中使用
构造方法
this():本类的构造
supper():父类的构造
方法的重写 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 public class Demo02 { public static void main (String[] args) { Demo03 demo03 = new Demo03 (); demo03.say(); Demo04 demo04 = new Demo03 (); demo04.say(); } }class Demo03 extends Demo04 { public static void say () { System.out.println("Demo03===>Hello World" ); } }class Demo04 { public static void say () { System.out.println("Demo04===>Hello World" ); } } Demo03===>Hello World Demo04===>Hello World Process finished with exit code 0
重写 :
方法名必须相同
参数列表必须相同
修饰符:范围可以扩大但不能缩小: pubilic >Protected>Default>private
抛出的异常:范围,可以缩小,但不能扩大: ClassNoFoundException –> Exception(大)
重写 ,子类的方法和父类不需要一致:方法体不同!
为什么要重写:父类的功能,子类不一定需要,或者不一定满足!
多态
动态编译: 类型 :可扩展性
即同一方法可以根据发送的对象的不同而采取多种不同的行为方式
一个对象的实际类型是确定的,但可以指向对象的引用类型有很多
多态存在的条件
有继承关系
子类重写父类的方法
父类引用指向子类对象
注意 :
多态是方法的多态,属性没有多态性
父类和子类,有联系 类型转换异常! ClassCastException!
存在条件 :继承关系,方法需要重写,父类引用指向子类对象 Father f1 = new Son();
以下没有多态 - static 方法 - final 常量 - private方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 public class Demo02 { public static void main (String[] args) { Demo03 demo = new Demo03 (); Demo04 demo2 = new Demo03 (); Object demo3 = new Demo03 (); demo.say(); demo2.say(); demo.run(); ((Demo03)demo2).run(); } }class Demo03 extends Demo04 { @Override public void say () { System.out.println("Demo03===>son" ); } public void run () { System.out.println("Run demo" ); } }class Demo04 { public void say () { System.out.println("Demo04===>father" ); } } Demo03===>son Demo03===>son Process finished with exit code 0
instanceof和类型转换 instanceof 判断类之间的关系
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 public class Demo02 { public static void main (String[] args) { Object object = new Student (); System.out.println(object instanceof Student); System.out.println(object instanceof Person); System.out.println(object instanceof Teacher); System.out.println(object instanceof Object); System.out.println(object instanceof String); System.out.println("================================================================" ); Person person = new Student (); System.out.println(person instanceof Student); System.out.println(person instanceof Person); System.out.println(person instanceof Teacher); System.out.println(person instanceof Object); System.out.println("================================================================" ); Student student = new Student (); System.out.println(student instanceof Student); System.out.println(student instanceof Person); System.out.println(student instanceof Object); } }class Person { public void run () { System.out.println("Runnable" ); } }class Student extends Person { }class Teacher extends Person { }true false true false ================================================================true true false true ================================================================true true true Process finished with exit code 0
类型转换
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 public class Demo02 { public void main (String[] args) { Student student = new Student (); Person person = new Student (); ((Student)student).go(); } class Person { public void run () { System.out.println("Runnable" ); } } class Student extends Person { public void go () { System.out.println("GO" ); } } class Teacher extends Person { } }
父类引用指向子类的对象
把子类转换为父类,向上转型
把父类转换为子类,向下转型;强制转换,丢失精度(丢失方法)
方便方法的调用,减少重复的代码!
static 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 public class Demo02 { public static void main (String[] args) { Student student = new Student (); System.out.println("================================================" ); Student student1 = new Student (); } }class Student { { System.out.println("默认代码块" ); } static { System.out.println("静态代码块" ); } public Student () { System.out.println("构造方法" ); } }
抽象类
abstract修饰符可以用来修饰方法也可以修饰类,如果修饰方法,那么该方法就是抽象方法;如果修饰类,那么该类就是抽象类。
抽象类中可以没有抽象方法,但是有抽象方法的类一定要声明为抽象类。
抽象类,不能使用new 关键字来创建对象,它是用来让子类继承的。
抽象方法,只有方法的声明,没有方法的实现,它是用来让子类实现的。
子类继承抽象类,那么就必须要实现抽象类没有实现的抽象方法,否则该子类也要声明为抽象类。
1 2 3 4 5 6 7 8 9 10 11 12 public abstrack class Action { public abstracct void doSomething () ; }
抽象类存在的意义和作用
抽象是将共性抽离出来,产生抽象性概念非具体。
抽象类和抽象方法作用: 使类的抽象性明确起来,告诉用户和编译器打算怎么使用他们。抽象类还是很有用的重构工具,因为它们使得我们可以很容易地将公共方法沿着继承层次结构向上移动。
抽象类不可实例化,抽象类包含普通方法和抽象方法。抽象方法只需声明无需方法体。
子类继承抽象类,父类的抽象方法必须被子类重写,普通方法可不需要重写。
接口的定义与实现
普通类:只有具体的实现
抽象类:具体实现和规范(抽象方法)都有!
接口:只有规范!
接口就是规范,定义的是一组规则
接口的本质是契约,规定好后大家都接受。
作用 :
约束
定义一些方法,让不同的人实现~ 10 ——— 1
public abstract
public statis final
接口不能被实例化~,接口中没有构造方法~
implemments可以实现多个接口
必须重写接口中的方法
接口
1 2 3 4 5 6 7 8 9 10 public interface UserService { void add (String username) ; void delete (String username) ; void update (String username) ; void query (String username) ; }
实现类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 public class UserServiceImpl implements UserService { @Override public void add (String username) { } @Override public void delete (String username) { } @Override public void update (String username) { } @Override public void query (String username) { } }
N种内部类
内部类就是在一个类的内部再定义一个类,比如,A类中定义了一个B类,那么B类相对A类来说就称为内部类,而A类相对B类来说就是外部类了
成员内部类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 class Circle { private double radius = 0 ; public static int count = 1 ; public Circle (double radius) { this .radius = radius; } class Draw { public void drawSahpe () { System.out.println(radius); System.out.println(count); } } }
2.局部内部类
局部内部类是定义在一个方法或者一个作用域里面的类,它和成员内部类的区别在于局部内部类的访问仅限于方法内或者该作用域内
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 class People { public People () { } } class Man { public Man () { } public People getWoman () { class Woman extends People { int age = 0 ; } return new Woman (); } }
3.匿名内部类
匿名内部类应该是平时我们编写代码时用得最多的,在编写事件监听的代码时使用匿名内部类不但方便,而且使代码更加容易维护。下面这段代码是一段Android事件监听代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 scan_bt.setOnClickListener(new OnClickListener () { @Override public void onClick (View v) { } }); history_bt.setOnClickListener(new OnClickListener () { @Override public void onClick (View v) { } });
4.静态内部类
静态内部类也是定义在另一个类里面的类,只不过在类的前面多了一个关键字static。静态内部类是不需要依赖于外部类的,这点和类的静态成员属性有点类似,并且它不能使用外部类的非static成员变量或者方法,这点很好理解,因为在没有外部类的对象的情况下,可以创建静态内部类的对象,如果允许访问外部类的非static成员就会产生矛盾,因为外部类的非static成员必须依附于具体的对象。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 public class Test { public static void main (String[] args) { Outter.Inner inner = new Outter .Inner(); } } class Outter { public Outter () { } static class Inner { public Inner () { } } }
2022-10-09 午