how2j基础
1.
public是访问修饰符,public,公共的,代表被他修饰的类、方法,变量是公共的其他代码都可以访问 static是静态修饰符,被他修饰的不需要实例化就可以使用 void是返回值类型,void代表没有返回值 String是变量类型,字符串类型 args是数的名字,看见String[]了吧,这说明是一个String类型的数组,而args是这个数组的名称
2.
final 修饰一个变量,有很多种说法,比如不能改变等等
准确的描述是 当一个变量被final修饰的时候,该变量只有一次赋值的机会
也就是说final变量如果在声明的时候被赋值了,那么以后他就再也不能被赋值,如果在声明的时候没有被赋值,那么以后仅能赋值一次,不然会报错。
3.
int[] a; 声明了一个数组变量。
[]表示该变量是一个数组
int 表示数组里的每一个元素都是一个整数
a 是变量名
但是,仅仅是这一句声明,不会创建数组有时候也会写成int a[];
int[] a=new int[5];这样才是声明加创建。
4.
数组分配空间同时赋值的写法:
int[] a = new int[]{100,102};
int[] a = {100,102};
5.
复制数组
System.arraycopy(src, srcPos, dest, destPos, length)
src: 源数组
srcPos: 从源数组复制数据的起始位置
dest: 目标数组
destPos: 复制到目标数组的起始位置
length: 复制的长度
6.Arrays 工具类
关键字 | 作用 |
---|---|
copyOfRange | 数组复制 |
toString() | 转换为字符串 |
sort | 排序 |
binarySearch | 搜索 |
equals | 判断是否相同 |
fill | 填充 |
需注意的是使用binarySearch前必须用sort对数组进行排序
7.二维数组的for each循环
for`(int[] i :a){
for(int j: i){
System.out.print(j +" ");
}
System.out.println();
第一层先把a的元素拿进循环,对应的类型是int[](就相当于把第一行的数组放进去)
第二次就是正常的for each循环
8.创建对象
new Hero();
代表创建了一个Hero对象
但是也仅仅是创建了一个对象,没有办法访问它
为了访问这个对象,会使用引用来代表这个对象
Hero h = new Hero();
h这个变量是Hero类型,又叫做引用
=的意思指的h这个引用代表右侧创建的对象
“代表” 在面向对象里,又叫做“指向”
先引用再创建
9.多个引用,一个对象
Hero h1 = new Hero();
Hero h2 = h1;
Hero h3 = h1;
引用之间的赋值,表示他们都指向(管理)同一个对象
10.方法重载
如果不清楚有多少个参数但是清楚参数的类型,就可以用可变数量的参数的写法
public void attack(Hero ...heros)
这样的话就会自动根据传入的参数进行不同的操作了
11.构造函数
通过一个类创建一个对象,这个过程叫做实例化
实例化是通过调用构造方法(又叫做构造器)实现的
如果类中没有构造方法,则会默认自动构造一个无参无内容的构造方法,如:
public Hero(){
}
12.this
在一个构造函数中调用另一个构造函数时使用this,不过要注意要写在第一行,并且只能有一个this.
public Hero(String name){
}
public Hero(String name,float hp){
this(name); //这样就调用了第一个构造方法,根据传入的参数的不同,会自动调用不同的构造方法
}
13.类类型的传参
public void revive(Hero h){
h = new Hero("提莫",383);
}
...
teemo.hp = teemo.hp - 400;
teemo.revive(teemo);
System.out.println(teemo.hp);
这样传参输出的还是-17 因为java是值传递,这个函数就是一个h,原本是指向teemo的,但是现在把它重新new指向了另一个对象,这样是对对原来的teemo没有任何影响,teemo中的数据没有丝毫会因为h的产生而改变,想要改变teemo指向h所指可以这么做
public Hero revive(Hero h){
h = new Hero("提莫",383);
return h;
}
...
teemo.hp = teemo.hp - 400;
teemo=teemo.revive(teemo);
System.out.println(teemo.hp);
这样的话就是把h指向的新的对象重新返回并且赋值给了teemo,这样的话teemo才能够被改变
也可以这样:
public void revive1(Hero h){
h.hp=383;
}
这样的意思就是,原本h就是和teemo一样指向同一个对象的,所以我们直接修改h指向的对象的值就是修改teemo指向的对象的值,因为根本上new的作用是让重新指向一个新的对象,对h改变了但是对temmo指向的对象没有丝毫变化,所以不行
14.包
使用同一个包下的其他类,直接使用即可
但是要使用其他包下的类,必须import
package charactor;
//Weapon类在其他包里,使用必须进行import
import property.Weapon;
- 属性通常使用private封装起来
- 方法一般使用public用于被调用
- 会被子类继承的方法,通常使用protected
作用范围最小原则:能用private就用private,不行就放大一级,用package,再不行就用protected,最后用public。 这样就能把数据尽量的封装起来,没有必要露出来的,就不用露出来了
15.类变量(类属性)
当一个属性被static修饰的时候,就叫做类属性,又叫做静态属性
当一个属性被声明成类属性,那么所有的对象,都共享一个值
类属性: 又叫做静态属性
对象属性: 又叫实例属性,非静态属性
如果一个属性声明成类属性,那么所有的对象,都共享这么一个值
访问类属性有两种方式
- 对象.类属性
teemo.copyright
- 类.类属性
Hero.copyright
简而言之就是说类变量是共享的,对象变量是每个对象私有的
16.单例模式
单例模式是指一个类中只有一个对象,对象new在类的内部,并且用private的构造函数使外部无法new新对象(不然会报错,因为是private的构造函数)
分为两种,一种是饿汉模式,就是无论如何都会创建一个新的对象(但是只有一个对象),另一种懒汉模式就是只有在满足一定条件的时候才会创建对象
饿汉模式如下:
public class GiantDragon {
//私有化构造方法使得该类无法在外部通过new 进行实例化
private GiantDragon(){ //这个很关键,构造方法必须是private的,不然无法实现单例模式,外部仍然可以创建新对象
}
//准备一个类属性,指向一个实例化对象。 因为是类属性,所以只有一个
private static GiantDragon instance = new GiantDragon();
public static GiantDragon getInstance(){
return instance;
}
}
17.枚举类
public enum Season {
SPRING,SUMMER,AUTUMN,WINTER
}
便于进行switch循环
18.造型
子类转父类都可以成功(向上造型),父类转子类需要强制转换(向下造型)
Hero h =new Hero();
ADHero ad = new ADHero();
h = ad;
ad = (ADHero) h;
类和接口之间也可以进行造型,类转换为接口时向上造型,接口转换为类是向下造型
向上转型的作用,用法
class Car {
public void run() {
System.out.println("这是父类run()方法");
}
public void speed() {
System.out.println("speed:0");
}
}
class BMW extends Car {
public void run() {
System.out.println("这是BMW的run()方法");
}
public void speed() {
System.out.println("speed:80");
}
}
public class Benz extends Car {
public void run() {
System.out.println("这是Benz的run()方法");
}
public void speed() {
System.out.println("speed:100");
}
public void price() {
System.out.println("Benz:800000$");
}
public static void main(String[] args) {
show(new Benz());//向上转型实现
show(new BMW());
}
public static void show(Car car) {//父类实例作为参数
car.run();
car.speed();
}
}
这里就是很好的展示了向上转型的作用,这个show函数,因为bmw和benz都要传进去,但是参数的类型只能写一个,所以这里就可以用向上转型,把父类的类型作为参数传入,那么这样子类都可以通过向上转型成父类的类型从而传入函数之中
19.多态
都是同一个类型,调用同一个方法,却能呈现不同的状态
要实现类的多态,需要如下条件:
1.父类(接口)引用指向子类对象(向上造型)
2.调用的方法有重写
简而言之就是父类中的某个方法调用时可以传入子类的参数,并且这个方法里调用了子类所重写的方法,不同子类都属于这个父类,但是调用父类这个方法时却会产生不同的效果
20.final
final修饰类不能够被继承
final修饰方法不能够被重写
final修饰基本类型变量表示该变量只有一次赋值机会
final修饰引用表示该引用只有1次指向对象的机会(就是只能指向一次对象,之后就不能改变了)
常量:static final
21.抽象类和接口的区别
区别1:
子类只能继承一个抽象类,不能继承多个
子类可以实现多个接口
区别2:
抽象类可以定义
public,protected,package,private
静态和非静态属性
final和非final属性
但是接口中声明的属性,只能是
public
static
final的
即便没有显式的声明
22.内部类
内部类分为四种:非静态内部类 静态内部类 匿名类 本地类
1.非静态内部类:只在外部类有对象存在时才能被初始化,例如:
public class Hero {
private String name;
// 非静态内部类,只有一个外部类对象存在的时候,才有意义
// 战斗成绩只有在一个英雄对象存在的时候才有意义
class BattleScore {
}
}
public static void main(String[] args) {
Hero garen = new Hero();
garen.name = "盖伦";
// 实例化内部类
// BattleScore对象只有在一个英雄对象存在的时候才有意义
// 所以其实例化必须建立在一个外部类对象的基础之上
BattleScore score = garen.new BattleScore();
}
}
2.静态内部类:静态内部类的实例化 不需要一个外部类的实例为基础,可以直接实例化
语法:new 外部类.静态内部类();
在静态内部类里面不可以访问外部类的实例属性和方法
除了可以访问外部类的私有静态成员外,静态内部类和普通类没什么大的区别
3.匿名类,可以通过匿名类直接实例化一个抽象类,就相当于时节省了初始化一个继承抽象类的子类然后再实例化,匿名类就是把中间这个过程直接省去
public abstract class Hero {
public abstract void attack();
public static void main(String[] args) {
Hero h = new Hero(){
//当场实现attack方法
public void attack() {
System.out.println("新的进攻手段");
}
};
h.attack();
//通过打印h,可以看到h这个对象属于Hero$1这么一个系统自动分配的类名
System.out.println(h);
}
}
4.本地类:就是有名字的匿名类,就是继承抽象类然后实例化
public abstract class Hero {
...
public abstract void attack();
public static void main(String[] args) {
class SomeHero extends Hero{
public void attack() {
...}
}
}
}
23.封装类
所有的基本类型,都有对应的类类型,比如int对应的类是Integer,这种类就叫做封装类
//基本类型转换成封装类型
Integer it = new Integer(i);
//封装类型转换成基本类型
int i2 = it.intValue();
//自动装箱
Integer it2 = i;
//自动拆箱
int i3 = it;
24.StringBuffer
StringBuffer是可变长的字符串,其余和字符串都一样,包括初始化赋值这种
public static void main(String[] args) {
class SomeHero extends Hero{
public void attack() {
…}
}
}
}
#### 23.封装类
所有的**基本类型**,都有对应的**类类型**,比如int对应的类是Integer,这种类就叫做封装类
```java
//基本类型转换成封装类型
Integer it = new Integer(i);
//封装类型转换成基本类型
int i2 = it.intValue();
//自动装箱
Integer it2 = i;
//自动拆箱
int i3 = it;
24.StringBuffer
StringBuffer是可变长的字符串,其余和字符串都一样,包括初始化赋值这种