Java基础整理之字节、数组、字符串、面向对象

一、字节(8个)
8bit = 1B或1byte
1024B = 1Kb


二、强制类型转换顺序及其大小顺序
遵循向上转换的规则
byte,short,char -> int -> long -> double

Byte    --  一个字节  2的1*8次方
Short   --  两个字节  2的2*8次方
Int     --  四个字节  2的4*8次方
Long    --  八个字节  2的8*8次方
Char    --  两个字节  2的2*8次方
Float   --  四个字节  2的4*8次方
Double  --  八个字节  2的8*8次方


注意事项byte,short,char相互之间不转换,他们参与运算首先转换为int类型


notes:
null是给引用数据类型赋值用的

ASCLL对应的:
0 --> 48
9 -->  57
A --> 65
Z --> 90
a --> 97
z --> 122
三、方法重载
1.方法名一样,参数不一样 || 返回值不一样(或的关系)2018.6.14 改为跟返回值没关系

四、数组 [] 
1.需要注意的事项
需要定义长度,创建对象
2.命名格式
数组:1。长度固定 2.同种数据类型元素
String [] arr = new String[3]  固定长度的数组
String [] arr = new String[]{"12ab","java","45Cd","Server78"}
String [] arr = {"12ab","java","45Cd","Server78"}

notes:
当数据确定时,建议用第三种,(静态初始化)
当数据不确定时,建议用第一种(动态初始化)
根据索引访问数组的元素

3.数组原理内存图、

区域名称    作用
寄存器 给CPU使用,和我们开发无关。
本地方法栈 JVM在使用操作系统功能的时候使用,和我们开发无关。
方法区 存储可以运行的class文件。
堆内存 存储对象或者数组,new来创建的,都存储在堆内存。
方法栈 方法运行时使用的内存,比如main方法运行,进入方法栈中执行


此处应有一个数组内存图
程序执行流程:
1.main方法进入方法栈执行
2.创建数组,jvm会在堆内存中开辟空间,存储数组
3.数组内存中会有自己的内存地址,以十六进制表示
4.数组中有自己定义长度,不给初始化值则默认是0
5.jvm将数组的内存地址赋值给引用类型变量arr
6.变量arr保存的是数组内存中的地址,而不是一个具体具体是数值,因此称为引用数据类型.


五、字符串
1.  3种构造方法
String str = String("你好")
char arr[] = {'h','e','l','l'}

String str1 = new String(arr); //hello
String str2 = new String(arr,0,3) //hel

2. 以下两种方式 对比其区别
方式1 String s = "hello";
方式2 String s = new String("hello")

情况1:常量池中有字符串常量"aaa"
通过方式1创建对象,程序运行时会在常量池中查找"aaa"字符串,将找到的"aaa"字符串地址赋值给s
通过方式2创建对象,无论常量池中有没有"aaa"字符串 程序都会在堆内存中开辟一片新的空间来存放新对象

情况1:常量池中没有字符串常量"aaa"
通过方式1创建对象,程序运行时会在常量池中查找"aaa"字符串,将找到的"aaa"字符串地址赋值给s

通过方式2创建对象,程序会在堆内存中开辟一片新空间存放新的对象,同时会将"aaa"字符存入常量池,相当于创建了2个对象

3.进行字符串比较时:
情况1:若是用 == 
(1)若是基本类型 则比较的是值是否相同
(2)若是引用类型 则比较地址是否相同

情况2:那咋比呢?
用equals进行比较
equals(String str) 比较的时内容
equalsIgnoreCase() 忽略大小写比较内容
4.String str.方法
concat()  将指定字符串连接到字符串末尾
charAt() 返回指定索引处的char值
indexOf() 返回指定字符串 第一次出现的 索引值
substring(int beginIndex) 返回一个字符串,从beginIndex开始截取字符串到末尾并返回ndex开始截取字符串到末尾并返回
substring(int beinIndex,int endIndex) 返回一个字符串,从beginIndex开始到endIndex结束
toUpperCase() 将字符串转换成 全部大写
toLowerCAse() 将字符串转换成 全部小写

5.Math基本方法
Math.方法
abs  -->返回 绝对值
radom() 返回一个double的正值 大于等于0.0 小于1.0
ceil() 返回大于等于参数的最小的整数
floor() -->返回一个小于或者等于参数的最大的整数
round() -->返回最接近参数的long(相当于四舍五入方法)

六、面向对象
1.重写 的理解
1.子类中出现与父类一样的方法时,会出现覆盖的操作
2.子类需要父类的功能,并且子类自己还有一些特定的内容,可以重写父类的方法
3.注意事项:
a.子类覆盖父类的方法,必须保证权限要大于等于父类的权限
b.子类与父类的方法声明必须一样:函数的返回值 函数名 参数列表一样

2.抽象

1.抽象方法的特点
a.只有方法声明没有方法主体
b.只能存在抽象类中


2.什么时候用抽象方法:
a.某个父类只知道子类应该有什么方法,但是不知道子类是怎么实现的
3.抽象类可以直接创建对象么?为什么
不可以,因为抽象类有抽象方法,new一个对象,调用抽象方法时无意义的
4.请问抽象类可以有构造方法吗,构造方法在抽象类有意义吗?
可以有 有意义 子类的构造方法可以调用抽象父类中的构造方法给成员变量进行赋值
5.抽象类一定时父类么?
抽象类一定是个父类,因为抽象类是不断抽取共性需求而来的
6.抽象类中可以没有抽象方法么?
可以,可以不定义抽象方法,此时仅仅是不让该类创建对象,用于某些特殊的需要
7.请问是先有抽象类还是先有子类?
设计时由具体抽取处抽象类,而开发阶段则应该先定义抽象类,再根据不同需要由父类定义子类

notes:
1.抽象类中不一定有抽象方法,但是抽象方法的类必定是抽象类
2.抽象类的子类,必须重写抽象父类中所有的抽象方法,否则,编译无法通过而报错,除非该子类也是抽象类



3.static关键字:
当static修饰成员变量时:
static关键字的使用,它可以用来修饰成员变量和成员方法,
被修饰的成员变量属于类,而不是单单属于某个对象,
也就是说被static修饰的成员变量既然属于类,就可以不靠创建对象调用了,
该类的每个对象都可以共享同一个类变量的值,任何对象都可以更改该类变量的值,
但也可以通过不创建该类变量的情况下对改类变量进行操作。

当static修饰方法时:
建议使用类名调用,而不需要创建类对象,

notes:
~静态方法可以直接访问静态类变量,和静态方法
~静态方法不能直接访问普通成员变量和方法,反之成员方法可以直接访问静态类变量或静态方法
~静态方法中,不能直接使用this关键字

被static修饰的成员建议通过类名直接访问,虽然可以通过对象名字访问静态成员,
原因既多个对象均属于一个类,共享使用同一个静态成员,但是不建议,会出现警告信息


4.静态代码块
~是随着类的加载而加载,且只加载一次。
~存储在内存中特殊的区域(静态区)所有可以直接被类名调用
~它优先与对象存在,所有,可以被所有对象共享


七、面向对象三大特征
1.封装
2.继承
继承:就是子类继承父类的属性和行为,使得子类对象具有与父类相同的属性、
相同的行为。子类可以直接 访问父类中的非私有的属性和行为。 

A.继承之后对 成员变量 产生的影响:

a.当子类与父类变量不重名则没有影响
b.当子类与父类变量重名时
会根据就近原则,优先使用子类的变量

notes:
怎么避免这样的情况:
可以根据 super.父类成员变量来访问父类非私有成员变量
通常编码时,我们遵循封装的原则,使用private修饰成员变量,
那么如何访问父类的私有成员 变量呢?对!可以在父类中提供公共的getXxx方法
和setXxx方法
可以根据 this.父类成员变量来访问当前成员变量

B.继承之后对 成员方法 的影响:

a.当子类与父类方法不重名则没有影响

b.当子类与父类方法重名时
这时的访问是一种特殊情况,叫做方法重写 (Override)。
方法重写:
子类中出现与父类一模一样的方法时(返回值类型,方法名和参数列表都相同),
会出现覆盖效 果,也称为重写或者复写。声明不变,重新实现。

notes:
1.子类必须保证权限大于或者等于父类权限
2.子类在进行覆盖时,必须要保证,返回值类型,方法名,参数列表一样

C.继承之后对 构造方法 的影响:
构造方法是一致的,所以子类是无法继承父类构造方法的
构造方法是初始化变量用的,在进行子类进行初始化的时候,默认会有一个super()来对父类进行初始化,父类初始化后才能给子类使用


3.多态
多态: 是指同一行为,具有多个不同表现形式。 

1.前提也是重点:
a.继承或者实现[二选一] 这是前提
b.方法重写[意义体现:不重写,无意义]
父类类型 变量名 = new 子类对象
变量名.方法名();
c.父类引用指向子类对象[格式体现]

当使用多态方式调用方法时,首先检查父类中是否有该方法,
如果没有,则编译错误;如果有,执行的是子类重写 后方法

2.引用类型转换
多态的类型分为向上转型和向下转型

向上转型:
多态本身就是子类类型向父类类型转换,默认执行,当一个父类类型指向一个子类类型时就是向上转型

向下转型:
父类类型向子类类型转换的过程,这个过程时强制的

格式:
子类类型 变量名 = (子类类型) 父类变量名;
如:Cat c = (Cat) a;
为啥要转型:?
当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误。也就是说,不能调用子类拥 有,而父类没有的方法。编译都错误,更别说运行了。这也是多态给我们带来的一点"小麻烦"。所以,想要调用子 类特有的方法,必须做向下转型

想要调用子类特有方法,需要转型

3.做类型校验
public class Test{
public static void main(String[] args){
// 向上转型
Animal a = new Cat();
a.eat();

// 向下转型
if (a instanceof Cat){
c.catchMouse(); // 调用的是 Cat的catchMouse
}else if (a instanceof Dog){
Dog d = (Dog)a;
d.watchHose() // 调用的是 Dog的 watchHose
}
}
}
? ????


八、接口
是java中一个引用类型,是方法的集合,如果说类的内部封装了成员变量,构造方法和成员方法,那么接口的内部主要时封装了方法,
包含了抽象方法(JDK7之前),默认方法和静态方法(jdk8),私有方法(jdk9)

接口包含抽象方法:
abstract 来修饰 也可以省略,没有方法体,该方法提供子类实现使用

接口包含抽象方法:
默认方法 使用 default 不可省略 供子类调用或者子类重写
静态方法 使用 static 修饰 供接口直接调用
私有方法 使用 private 修饰 供接口中的默认方法或者静态方法调用

notes:
非抽象子类实现接口:
1.必须重写接口中所有抽象方法
2.继承了接口的默认方法,即可直接调用,也可以重写
接口的静态方法的使用:
只能使用接口名调用,不可以通过实现类的类名或者实现类的对象调用,
接口私有方法的使用:
私有方法:只有默认方法可以调用
私有静态方法:默认方法和静态方法可以调用

接口中,有多个抽象方法时,实现类必须重写所有抽象方法。如果抽象方法有重名的,只需要重写一次。代码如 下:
接口中,有多个默认方法时,实现类都可继承使用。如果默认方法有重名的,必须重写一次
接口中,存在同名的静态方法并不会冲突,原因是只能通过各自接口名访问静态方法



子接口重写默认方法时,default关键字可以保留。 
子类重写默认方法时,default关键字不可以保留。

接口中,无法定义成员变量,但是可以定义常量,其值不可以改变,默认使用public static ?nal修饰。 
接口中,没有构造方法,不能创建对象。 
接口中,没有静态代码块


notes:
数组和类作为返回值时 返回一个地址,这个地址在数组中表示的是一个空间,在类里面表示的是一个对象
接口作为返回值时 返回一个地址,是一个接口的子对象


九、final 关键字

final: 不可改变。可以用于修饰类、方法和变量。 

类:被修饰的类,不能被继承。但是可以继承其他类 
方法:被修饰的方法,不能被重写。 父类中方法没有final 子类覆盖后可以加final
变量:被修饰的变量,不能被重新赋值。

1.修饰变量
1.局部变量 -- 基本类型
基本类型的局部变量,被final修饰后,只能赋值一次,不能再更改

2.局部变量 -- 引用类型
引用类型的局部变量,被fianl修饰后,只能指向一个对象,表示地址不能再更改,但是不影响对象内部的成员变量赋值

3.成员变量
被final修饰的常量名称,一般都有书写规范,所有字母都大写

2.请写出final的特点及final可以修饰什么
2.1 ?final修饰类不可以被继承,但是可以继承其他类。
2.2   final修饰的方法不可以被覆盖,但父类中没有被final修饰方法,子类覆盖后可以加final。
2.3 ?final修饰的变量称为常量,这些变量只能赋值一次。
2.4 ?引用类型的变量值为对象地址值,地址值不能更改,但是地址内的对象属性值可以修改。
2.5 ?修饰成员变量,需要在创建对象前赋值,否则报错。(当没有显式赋值时,多个构造方法的均需要为其赋值。)
2.6   final关键字是一个修饰符,可以修饰类,方法,局部变量,成员变量
权限修饰符:
public protected default private  权限由大到小

没有特殊考虑,建议这样使用权限
1.成员变量使用private,隐藏细节
2.构造方法使用public,方便创建对象
3.成员方法使用public,方便调用对象

notes:
不加权限修饰,其访问能力与default修饰符相同

内部类:
1.定义:
将一个类A定义在另一个类B里面,里面的那个类A就称为内部类,B则称为外部类。 

2.成员内部类 :定义在类中方法外的类
class 外部类 {
class 内部类{

}

3.在描述事物时,若一个事物内部还包含其他事物,就可以使用内部类这种结构。比如,汽车类 Car 中包含发动机 类 Engine ,这时, Engine 就可以使用内部类来描述,定义在成员位置
4.内部类特点:
内部类可以直接访问外部类的成员,包括私有成员。 
外部类要访问内部类的成员,必须要建立内部类的对象

格式:
public class InnerDemo{
// 创建外部类对象
Person p = new Person();

// 创建内部类对象
Heart heart = p.new Heart();

//调用内部类方法
heart.jump();

//调用外部类方法
p.setLive(false)

//调用内部类方法
heart.jump()
}

notes:
内部类仍然是一个独立的类,在编译之后会内部类会被编译成独立的.class文件,但是前面冠以外部类的类名 和$符号 。
比如,Person$Heart.class 

4.匿名内部类:
是内部类的简化写法.他的本质时一个带具体实现的父类或者父接口的匿名子类对象
开发中,最常用到内部类.以接口举例,当你使用一个接口时,需要做以下4个步骤
1. 定义子类 
2. 重写接口中的方法 
3. 创建子类对象 
4. 调用重写后的方法

在使用匿名内部类时的前提:
匿名内部类必须继承一个父类或者实现一个父接口

格式:
new 父类名或者接口名(){
@Override
public void method(){
// 方法体
}
}

创建匿名内部类,并调用;
public class InnerDemo {
public static void main(String[] args) {
/*
1.等号右边:是匿名内部类,定义并创建该接口的子类对象
2.等号左边:是多态赋值,接口类型引用指向子类对象
*/
FlyAble f = new FlyAble(){
@Override
public void fly() {
System.out.println("︿( ̄︶ ̄)︿");
}
};


f.fly();
}
}


通常在方法的形式参数是接口或者抽象类时,也可以将匿名内部类作为参数传递。代码如下


public class InnerDemo1 {
public static void main(String[] args) {
FlyAble f = new FlyAble(){
public void fly() {
System.out.println("︿( ̄︶ ̄)︿");
}
};


showFly(f);
}
    
public static void showFly(FlyAble f){
f.fly();
}
}

可以将上述步骤进行转换成更简单的一步:

public class InnerDemo3 {
    public static void main(String[] args) {
        showFly(new FlyAble(){
            public void fly() {
                System.out.println("︿( ̄︶ ̄)︿");
            }
        });
    }


    public static void showFly(FlyAble f){
        f.fly();
    }
}


5.引用类型用法总结

















原文地址:https://www.cnblogs.com/zhengyuan/p/9257418.html