包含的内容有:for循环、while循环、switch语句,if语句
public static void main(String[] args) {
int a=0;
for (int i = 0; i <10 ; i++) {
a+=1;
}
while (a>0){
if(a%2==0){
System.out.println(a+"是偶数");
}
else{
System.out.println(a+"是奇数");
}
a-=1;
}
switch(a){
case 0:
System.out.println("a是"+0);
break;
case 1:
System.out.println("a是"+1);
break;
}
}
primitive主数据类型+引用=变量
类型 | 位数 | 值域 |
---|---|---|
boolean | JVM决定 | true或false |
char | 16 bits | 0~65535 |
byte | 8 bits | -128~127 |
short | 16 bits | -32768~32767 |
int | 32 bits | ±2147483648 |
long | 64 bits | - 很大 ~ + 很大 |
float | 32 bits | 范围规模可变 |
double | 64 bits | 范围规模可变 |
注意,整数默认为int类型,小数默认为double类型,在创建其他类型变量以及运算时要标明。
float a=1.5f;//这个f不写则1.5默认为double,然后由double转为float
当大杯转小杯时可能会导致数据溢出,因此要注意数据的范围,以此来选择数据类型。
当编译器无法识别能否进行数据转化时,需要进行强制转换。
public class test {
public static void main(String[] args) {
long a=123;
//int b=a;会报错,编译不通过
int b=(int) a;
System.out.println(a);
}
}
自动强制转换的规则:
如果一个变量是类类型,而非基本类型,那么该变量又叫引用。
可以把实例化的对象的reference当做一个遥控器,远程遥控其他的行为。
当实例化一个对象的时候,会创建一个遥控器,遥控器在栈区,对象在堆区。
Book b=new Book();//new Book();只是创建一个对象,前面的b表示引用指向他,等号表示指向
Book c=new Book();
Book d=c;//这时候c和d两个遥控器遥控一个对象
c=b;//这时候c和b遥控同一个对象,但是d仍然遥控自己的那个对象
运算符 | 描述 |
---|---|
&& | 与 |
|| | 或 |
!= | 不等于 |
! | 非 |
短运算符
比如&&,当两端都为真才得到真,当左边为假便不会再计算右边
长运算符
比如&,强制虚拟机必须做两端的操作
符号 | 描述 |
---|---|
+ | 加 |
- | 减 |
* | 乘 |
/ | 除 |
% | 取余 |
++ | 自增 |
– | 自减 |
符号 | 描述 |
---|---|
> | 大于 |
>= | 大于或等于 |
< | 小于 |
<= | 小于或等于 |
== | 是否相等 |
!= | 不等于 |
参见ACM——位运算符整理
用的不多,用来提高运算速度,可以忽略不学。
符号 | 描述 |
---|---|
+= | a=a+x |
-= | a=a-x |
*= | a=a*x |
/= | a=a/x |
%= | a=a%x |
&= | a=a&x |
|= | a=a|x |
^= | a=a^x |
>>= | a=a>>x |
<<= | a=a< |
(判断)?A:B;
当判断的内容为真时返回A,否则返回B
int k = i < j ? 99 : 88;
数组是一个固定长度,包含相同类型数据的容器,具有默认值
public class demo extends test{
public static void main(String[] args) {
int []a=new int[5];//或者是写int a[]=new int[5];
int []b = new int[]{
100,102,444,836,3236};
a[0]=15;
System.out.println(a[0]);
System.out.println(a.length);
}
}
或者使用Arrays类的方法,或者是
复制数组: System.arraycopy(src, srcPos, dest, destPos, length)
public static void main(String[] args) {
int a [] = new int[]{
18,62,68,82,65,9};
int b[] = new int[3];//分配了长度是3的空间,但是没有赋值
//通过数组赋值把,a数组的前3位赋值到b数组
System.arraycopy(a, 0, b, 0, 3);
//把内容打印出来
for (int i:b) {
System.out.print(b[i] + " ");
}
}
public static void main(String[] args) {
//初始化二维数组,
int[][] a = new int[2][3]; //有两个一维数组,每个一维数组的长度是3
a[1][2] = 5; //可以直接访问一维数组,因为已经分配了空间
//只分配了二维数组
int[][] b = new int[2][]; //有两个一维数组,每个一维数组的长度暂未分配
b[0] =new int[3]; //必须事先分配长度,才可以访问
b[0][2] = 5;
//指定内容的同时,分配空间
int[][] c = new int[][]{
{
1,2,4}, {
4,5}, {
6,7,8,9}};
}
格式:可以通过values.for
快捷键实现
for (int each : values) {
System.out.println(each);//do something
}
包:import java.util.Arrays;
常用方法:
方法 | 描述 | 作用 |
---|---|---|
int[] b = Arrays.copyOfRange(a, 0, 3); | a是原数组,0取的到,3取不到 | 数组复制 |
String content = Arrays.toString(a); | a是数组,得到[18, 62, 68, 82, 65, 9] | 转换为字符串 |
Arrays.sort(a); | a是数组 | 升序排序 |
Arrays.binarySearch(a, 62 ): |
62是要搜索的元素 | 搜索,前提是升序排列了,不存在返回负数 |
Arrays.equals(a, b) | ab为两个数组 | 判断两个数组是否相同 |
Arrays.fill(a, 5 ); |
填充a数组全为5 | 填充(初始化) |
Dog[] myDogs=new Dog[3];
myDogs[0]=new Dog();//放咖啡的杯子就只能放咖啡
myDogs[0].name="Fido";
myDogs[0].bark();
在创建数据时,标明private,否则实例化的对象可以直接修改对应的值,把内裤给别人看了就挺尴尬的…
可以创建对应的方法来获取或者设置相应数据,比如
public void setname(String newname){
name=newname+getname();
}
当你仅仅只是声明一个变量,但是不初始化的时候,java会默认给你赋一个值
数据类型 | 默认值 |
---|---|
integers | 0 |
floating points | 0.0 |
boolean | false |
references | null |
实例变量是声明在类里面的,局部变量是声明在类的方法里的,局部变量在使用前必须要先赋值,否则编译器会报错。
在参数位置加三个点,例如
public void attack(Hero ... heros){
for (Hero:heros) {
//do something
}
}
//传参时参数用逗号隔开
声明为public,构造函数可以重载哦,注意别写void ,否则就成了普通方法
class demo {
public demo(String a){
System.out.println("调用了构造函数参数是"+a);
}
public demo(){
System.out.println("调用了默认构造");
}
public static void main(String[] args) {
demo test1=new demo("草");
demo test2=new demo();
}
}
指向当前类本身的元素,类似c++,即使是同名的,this.name=name;
也可以赋值,称为隐式调用。
但是只要和属性不同名,直接赋值也OK的,this还能实现构造方法
的相互调用
要访问别的class用import导入哦,import package.class
标黄了就表示不能访问到,不写默认为protected
自身 | 同包子类 | 不同包子类 | 同包类 | 其他类 | |
---|---|---|---|---|---|
private | 访问 | 继承 | 继承 | 访问 | 访问 |
protected | 访问 | 继承 | 继承 | 访问 | 访问 |
public | 访问 | 继承 | 继承 | 访问 | 访问 |
package | 访问 | 继承 | 继承 | 访问 | 访问 |
对象属性初始化有3种
"some hero"
;封装是面向对象三大特征之一(封装、继承、多态),是面向对象编程语言对客观世界的模拟,客观世界里成员变量都是隐藏在对象内部的,外界是无法直接操作的
将类的某些信息隐藏在类的内部,不允许外部程序直接访问,而是通过该类提供的方法来实现对隐藏信息的操作与访问,成员变量设置为private
,提供对应的getAbb
和setAbb
方法
子类继承父类可以获得父类的属性和方法,一个父类可以被多个子类继承,但是一个子类只能继承一个父类,不过一个类可以实现多个接口,Object类是所有类的父类,类的继承关键字是extents
在子类方法中寻找一个变量时如下顺序:
子类中的所有构造方法都会默认先访问父类的无参构造方法
,子类会继承父类的数据,因此在子类初始化前一定要先进行父类初始化,每一个子类第一句话默认都是super()
顺序如下:先当前再长远
实例化子类的时候,会先调用父类的构造方法,当多个构造方法时,默认调用父类无参构造方法
如果想调用父类带参构造,需要用super,例如
super(name);//在ADHero带参构造下写,这个相当于调用参数为name的父类构造方法
super.speed;//父类的属性
super.useItem();//父类的方法
this是访问或调用本类的成员变量或方法,supper是操作父类的
静态变量与静态初始块只会初始化一次,但是类成员变量在每次初始化都会进行初始化,而且是先进行成员变量的初始化再调用构造函数
父类静态变量 > 父类静态初始块 > 子类静态变量 > 子类静态初始块 > 父类成员变量 > 父类非静态初始块 > 父类构造器 > 子类成员变量 > 子类非静态初始块 > 子类构造器
当子类需要父类的功能,而功能主题子类有自己特有内容时,可以重写父类的方法,这样既沿袭了父类的功能,又定义了子类独有的内容。如果在子类中定义一个方法,其名称、返回类型及参数签名正好与父类中某个方法的名称、返回类型及参数签名相匹配,就说子类的方法覆盖了父类的方法。简单来说,子类的方法和父类一模一样
就说覆盖,注解是@Override
四个特点:
四个注意事项:(多态语法)
多态是同一对象在不同时刻表现出来的不同形态
多态的形式:
多态的前提和体现:
操作符的多态:
类的多态:
/**
LifePotion(血瓶)和MagicPotion(魔瓶)都继承于Item,当使用effect方法时只需要传入Item对象即可,
不用再写useLifePotion和useMagicPotion两个方法
*/
public class Hero {
public String name;
protected float hp;
public void useItem(Item i){
i.effect();
}
public static void main(String[] args) {
Hero garen = new Hero();
garen.name = "盖伦";
LifePotion lp =new LifePotion();
MagicPotion mp =new MagicPotion();
garen.useItem(lp);
garen.useItem(mp);
}
}
多态的优点:
多态的弊端:
instanceof判断引用是否指向对象
子类转父类,向上:ADHero引用转Hero引用是完全没问题的
父类转子类,向下:需要用到子类的类名进行强制转化,为什么要加呢,因为不知道子类的引用指向的对象是谁,
注:父类转子类之后再转子类可能会报错
https://www.bilibili.com/video/BV18J411W7cE?p=173
只对方法进行声明,而不去实现,在java中,一个没有方法体的方法称为抽象方法,如果类中有抽象方法,该类必须定义为抽象类
abstruct
进行修饰该抽象类的子类对象
该抽象类的子类对象
接口就像一种公共规范,只要符合规范标准,大家就可以通用。Java中的接口更多体现在对行为的抽象
interface
修饰implements
表示成员变量只能是常量,默认修饰符:public static final
接口没有构造方法,因为接口更多的是体现在对行为的抽象
成员方法只能是抽象方法
,默认修饰符:public abstruct
JDK8之后接口都有了默认实现,可以在实现的类中直接调用
接口就像约定,接口定义某些方法,交给某个类去实现,一个类可以实现多个接口 用逗号隔开就行
接口定义关键字:interface
public interface AD{
public void physicAttack();
}
类去实现接口的关键字:implements
public class ADHero extends Hero implements AD{
public void physicAttack(){
System.out.println("发起进攻");
}
}
注意,假如类不实现接口约定的方法,这个类会报错。
注:可以继承一个类时同时实现多个接口
# 成员区别
抽象类---->常量和变量,可以定义四种访问权限,有构造方法,有抽象方法,也有非抽象方法
接口------>只有公共的静态的常量和抽象方法
# 关系区别
抽象类---->只能被单继承
接口------>可以被类多实现(被其他接口多继承)
# 设计理念区别
抽象类---->抽象类是对类抽象,是对根源的抽象,包括属性和行为,抽象类反映的是is-a关系,表示这个对象是什么
接口------>主要是对行为动作的抽象,接口反映的是like-a关系,表示这个对象能做什么,接口是更加纯粹的抽象。
注:最大的相同点是抽象类和接口都不能直接实例化
该接口的实现类对象
该接口的实现类对象
例如我们想升级接口,但是如果升级的话所有的实现类都需要实现这个新方法,可以使用一个新接口继承这个接口,然后找类去实现它,但是太麻烦了,于是有了默认实现方法
public interface Test{
public default void show() {
//public可以省略,但是default不行
System.out.println("默认方法执行了,冲!");
}
}
静态方法只能被接口调用,这样做的目的是防止实现多个接口的时候,这多个接口存在同一个静态方法,导致混乱
public interface Test{
public static void show() {
System.out.println("静态方法执行了,冲!");
}
}
public class TestInterface{
public void main(String[] args) {
Test.show();
}
}
Java 9中新增了带方法体的私有方法,这其实在Java8中就埋下了伏笔:Java8允许在接口中定义带方法体的默认方法和静态方法。这样可能就会引发一个问题:当两个默认方法或者静态方法中包含一段相同的代码实现时,程序必然考虑将这段实现代码抽取成一个共性方法
,而这个共性方法是不需要让别人使用的,因此用私有给隐藏起来,这就是Java9增加私有方法的必然性
定义的格式:
private 返回值类型 方法名(参数列表)
private static 返回值类型 方法名(参数列表)
内部类就是在类中定义一个类,例如在类A中定义了类B,这个类B就是内部类,
按照内部类在类中定义的位置不同,可以分为两种形式:
内部类的定义格式如下:
public class ClassNameA{
修饰符 class ClassNameB{
}
}
内部类:java文件的class里面的类,属性和方法平等的位置
如何访问内部类呢?
外部类名.内部类名 对象名 = 外部类名.内部类名
通常情况下,我们把类做成内部类的目的就是不让别人访问到,因此通常是将内部类修饰为private
,外部类定义一个方法去调用内部类的函数,我们只需要调用外部对象的该方法即可
如果想调用局部内部类只能是在方法中创建内部类对象,然后使用内部类对象去访问方法
public class Test {
public int num = 10;
public void method() {
class Inner {
public void show(){
System.out.println(num);
}
}
Inner inner = new Inner();
inner.show();
}
public static void main(String[] args) {
Outer outer = new Outer();
outer.method();
}
}
通过new 外部类().new 内部类()
的形式去使用
Hero garen = new Hero();
BattleScore score = garen.new BattleScore();
static修饰,就不用再创建外部类
Hero.EnemyCrystal crystal = new Hero.EnemyCrystal();
前提是存在一个类,这个类可以是具体类也可以是抽象类,格式如下:
xxxx = new ClassNameOrInterfaceName(){
//重写方法
}
Hero是一个抽象类(abstruct),重写方法表示继承了这个类或实现了这个接口
Hero hero = new Hero(){
//实现一个attack新方法
public void attack() {
System.out.println("新的进攻手段");
}
};
hero.attack();
///--------也可以------//
new Hero(){
//实现一个attack新方法
public void attack() {
System.out.println("新的进攻手段");
}
}.attack();
匿名内部类的本质是继承了该类或实现了该接口的匿名对象
内部类与匿名类不一样的是,内部类必须声明在成员的位置,即与属性和方法平等的位置
本地类和匿名类一样,直接声明在代码块里面,可以是主方法,for循环里等等地方
public abstract class Hero {
String name; //姓名
float hp; //血量
float armor; //护甲
int moveSpeed; //移动速度
public abstract void attack();
public static void main(String[] args) {
//与匿名类的区别在于,本地类有了自定义的类名
class SomeHero extends Hero{
public void attack() {
System.out.println( name+ " 新的进攻手段");
}
}
SomeHero h =new SomeHero();
h.name ="地卜师";
h.attack();
}
}
//一个int类型数据
int i = 5;
//基本类型转换成封装类型
Integer it = new Integer(i);
//一个封装类型
Integer it = new Integer(5);
//封装类型转换成基本类型
int i2 = it.intValue();
基本数据类型通过等号转换为包装类,称为装箱
int i = 5;
//自动装箱为Integer类型
Integer it2 = i;
包装类通过等号转为基本数据类型,称为拆箱
Integer it = new Integer(5);
//自动拆箱为int基本数据类型
int i3 = it;
//int的最大值
System.out.println(Integer.MAX_VALUE);
//int的最小值
System.out.println(Integer.MIN_VALUE);
数字–>字符串(第二种方式不介绍了)
String str = String.valueOf(5);
//或者是String str = 5+"";
字符串–>数字
int i= Integer.parseInt("15");
printf和format能够达到一模一样的效果,如何通过eclipse查看java源代码 可以看到,在printf中直接调用了format
String sentenceFormat ="%s 在进行了连续 %d 次击杀后,获得了 %s 的称号%n";
System.out.printf(sentenceFormat,name,kill,title);
char用来保存一个字符,char对应的封装类是Character
public class TestChar {
public static void main(String[] args) {
System.out.println(Character.isLetter('a'));//判断是否为字母
System.out.println(Character.isDigit('a')); //判断是否为数字
System.out.println(Character.isWhitespace(' ')); //是否是空白
System.out.println(Character.isUpperCase('a')); //是否是大写
System.out.println(Character.isLowerCase('a')); //是否是小写
System.out.println(Character.toUpperCase('a')); //转换为大写
System.out.println(Character.toLowerCase('A')); //转换为小写
String a = 'a'; //不能够直接把一个字符转换成字符串
String a2 = Character.toString('a'); //转换为字符串
}
}
charAt | 获取字符 |
---|---|
toCharArray | 获取对应的字符数组 |
subString | 截取子字符串 |
split | 分隔 |
trim | 去掉首尾空格 |
toLowerCase toUpperCase | 大小写 |
indexOf lastIndexOf contains | 定位 |
replaceAll replaceFirst | 替换 |
startsWith | 以…开始 |
endsWith | 以…结束 |
equals | 判断是否相等 |
equalsIgnoreCase | 忽略大小写判断是否相等 |
package character;
public class TestString {
public static void main(String[] args) {
String str1 = "let there ";
StringBuffer sb = new StringBuffer(str1); //根据str1创建一个StringBuffer对象
sb.append("be light"); //在最后追加
System.out.println(sb);
sb.delete(4, 10);//删除4-10之间的字符,都是闭区间
System.out.println(sb);
sb.insert(4, "there ");//在4这个位置插入 there
System.out.println(sb);
sb.reverse(); //反转
System.out.println(sb);
}
}
StringBuffer与StringBuilder的区别是:StringBuilder是线程安全的
方法 | 描述 |
---|---|
Random random = new Random(10); | 10是seed,可以不写 |
random.nextInt(10) | 随机在最小int~最大int取一个数 |
random.nextInt(10) | [0,x)的随机整数,x不能小于0 |
nextFloat() | 随机一个float |
nextDouble() | 随机一个Double |
nextLong() | 随机一个Long |
nextBoolean() | 随机true或false |
nextBytes(byte[] bytes) | 为一个byte类型的数组随机赋值 |
nextGaussian() | 随机生成一个高斯分布的浮点数 |
方法 | 描述 |
---|---|
Math.abs() | 取绝对值 |
Math.ceil() | 向上取整 |
Math.floor() | 向下取整 |
Math.round(float a) | 四舍五入取整 |
Math.max(int a,int b) | 去较大的值 |
Math.min(int a,int b) | 去较小的值 |
Math.pow(double a,double b) | a的b次幂 |
Math.random() | 返回一个[0.0,1.0)之间的double值 |
方法 | 描述 |
---|---|
System.currentTimeMillis() | 获取系统当前毫秒值 |
System.exit(0); | 结束正在运行的Java程序 |
System.gc(); | 垃圾回收器 |
System.getProperties() | 确定当前的系统属性 |
System.arraycopy(src, 2, dest, 0, 2); | 复制数组 |
注意:是java.util.Date;
而非 java.sql.Date,此类是给数据库访问的时候使用的
零这个数字,就代表Java中的时间原点,其对应的日期是1970年1月1日 8点0分0秒 ,
为什么对应1970年呢? 因为1969年发布了第一个 UNIX 版本:AT&T,综合考虑,当时就把1970年当做了时间原点。
所有的日期,都是以为这个0点为基准,每过一毫秒,就+1。
// 当前时间
Date d1 = new Date();
System.out.println(d1);
// 从1970年1月1日 早上8点0分0秒 开始经历的毫秒数
Date d2 = new Date(5000);
System.out.println(d2);
返回long型的时间戳,直接打印对象,会看到 “Tue Jan 05 09:51:48 CST 2016” 这样的格式,可读性比较差,可以进行日期格式化
注:System.currentTimeMillis()
也可以达到gettime()的功能,而且更精确
package date;
import java.text.SimpleDateFormat;
import java.util.Date;
public class TestDate {
public static void main(String[] args) {
SimpleDateFormat sdf =new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS" );
Date d= new Date();
String str = sdf.format(d);
System.out.println("当前时间通过 yyyy-MM-dd HH:mm:ss SSS 格式化后的输出: "+str);
}
}
日历类可以转为日期类,还能翻日历,别鸡巴学了,感觉没啥用啊
import java.util.Calendar;
import java.util.Date;
public class TestDate {
public static void main(String[] args) {
//采用单例模式获取日历对象Calendar.getInstance();
Calendar c = Calendar.getInstance();
//通过日历对象得到日期对象
Date d = c.getTime();
Date d2 = new Date(0);
c.setTime(d2); //把这个日历,调成日期 : 1970.1.1 08:00:00
}
}
所有的饮用都能访问,用static修饰,到时候直接用 类+原点操作符
就能直接调用
例如Math库的Pi,math.pi
修饰类。这个类不能够被继承
修饰方法。这个方法不能够被重写
修饰基本类型变量。该变量只有一次赋值机会
修饰引用。表示该引用只有1次指向对象的机会
修饰常量。表示可以直接访问当不能修改的常量
public static final int itemTotalNumber = 6;
在类中声明一个方法,这个方法没有实现体,是一个“空”方法 ,即抽象方法。
一个类有抽象方法,就必须声明为抽象类。一个抽象类可以没有抽象方法。
抽象类不能直接实例化,只能通过子类来实例化
一个子类继承了抽象类就必须重写抽象方法,重写的时候就不用写abstract了
预祝大家学习进步✔