JavaSe第三天笔记小记
JavaSE第三天学习小记
1、java数组
与c++中的数组概念一致,把不同的只是语法
public class Hello {
public static void main(String[] args) {
/*效果相同
int[] arr; // 首选
int arr[]; // 可用,但java中不建议用
*/
int[] array1 = new int[5]; // 开辟五个存放int类型的数组
int[] array2 = {1, 2, 3}; // 开辟分别存放1,2,3的数组
System.out.println("获取数组大小:" + array1.length);
}
}
基本特点:
- 长度确定,一旦被创建,大小不可改变
- 存放元素必须是同一类型
- 数组中的元素可以是任何数据类型,包括基本类型和引用类型
- 数组变量属于引用类型,数组也可以看作是对象,数组中的每个元素相当于该对象的成员变量
- 数组本身就是对象,java对象是在堆中的,因此数组无论保存原始类型还是其他对象类型,数组本身都是在堆中的
三种初始化方式
1、静态初始化
int[] arr = {1,2,3};
Man[] mans = {new Man(1), new Man(2)};
2、动态初始化
int[] arr = new int[2];
arr[0] = 1;
arr[1] = 2;
3、数组的默认初始化
- 数组是引用类型,它的元素相当于类的实例变量,因此数组一经分配空间,其中的每个元素也被按照实例变量同样的方式被隐式初始化
2、内存分析
3、Arrays类
java中的一个工具类,包含在java.util.Arrays
包中
- 数组本身没有方法供我们调用,所以API中提供了一个工具类Arrays供我们使用,从而可以对数据对象进行一些基本的操作
- 查看JDK帮助文档
- Arrays类中的方法都是static修饰的静态方法,在使用的时候可以直接使用类名进行调用,而“不用”使用对象调用(是“不用”而不是“不能“)
常用方法:
- 给数组赋值:通过fill方法
- 对数组排序:通过sort方法,默认是从小到大排序
- 比较数组:通过equals方法比较数组中元素值是否相等
- 查找数组元素:通过binarySearch方法能对排序好的数组进行二分查找法操作
4、冒泡排序
动图演示:
import java.util.Arrays;
public class Hello {
public static void main(String[] args) {
int[] arr = {21, 26, 12, 45, 23, 9, 12, 3, 3, 7};
sort(arr);
System.out.println(Arrays.toString(arr));
}
public static void sort(int[] a) {
// 冒泡排序算法实现
for (int i = 0; i < a.length - 1; i++) {
for (int j = 0; j < a.length - 1 - i; j++) {
if (a[j + 1] < a[j]) {
int tmp = a[j];
a[j] = a[j + 1];
a[j + 1] = tmp;
}
}
}
}
}
结果:[3, 3, 7, 9, 12, 12, 21, 23, 26, 45]
5、面向对象
java中的面向对象思想与c++大体一致
- 以类的方式组织代码,以对象的方式组织(封装)数据
5.1 构造器
即构造方法(c++里面的构造函数)
- 必须和类的名字相同
- 不能有返回类型,也不能写void
- 使用new关键字创建对象的本质是在调用构造器
- 一旦定义了有参构造,就没有默认的隐式无参构造函数,因此需要显式定义
5.2 访问权限
修饰符 | 描述 | 大白话 |
---|---|---|
private | 私有的,被private修饰的类、方法、属性、只能被本类的对象所访问 | 我什么都不跟别人分享。只有自己知道 |
default | 默认的,在这种模式下,只能在同一个包内访问 | 我的东西可以和跟我一块住的那个人分享 |
protected | 受保护的,被protected修饰的类、方法、属性、只能被本类、本包、不同包的子类所访问 | 我的东西我可以和跟我一块住的那个人分享。另外也可以跟不在家的儿子分享消息,打电话 |
public | 公共的,被public修饰的类、方法、属性、可以跨类和跨包访问 | 我的东西大家任何人都可以分享 |
5.3 封装
- 程序设计追求“高内聚,低耦合”
- 数据的隐藏,通常应禁止直接访问一个对象中数据的实际表示,而应通过操作接口来访问
- 属性私有,get/set
5.4 继承
- 继承的本质是对某一批类的抽象,从而实现对现实世界更好的建模
extends
的意思是扩展,子类是父类的扩展- java中只有单继承,没有多继承
class People {
String name;
int age;
}
public class Student extends People{
// 继承了父类,具有父类的属性
}
object类
- java中所有的类,都默认直接或者间接继承Object
super
- super调用父类的构造方法,必须在构造方法的第一行
- super必须只能出现在子类的方法或者构造方法中
- super和this不能同时调用构造方法
- 只能在继承条件下才可以使用
this
- 与super相比代表的对象不同:本身调用者这个对象
- 没有继承也可以使用
this(); // 调用本类的构造
super(); // 调用父类的构造
5.5 重写与多态
重写:子类的方法与父类的方法必须相同,但是方法体不同
为什么需要重写:
- 父类的功能子类不一定需要或者不一定满足
重写的条件:
- 方法名必须相同
- 参数列表必须相同
- 修饰符:范围可以扩大但是不能缩小
- 抛出的异常:范围可以被缩小但是不能扩大
多态:即同一方法可以根据发送对象的不同而采取多种不同行为
- 一个对象的实际类型是确定的,但是指向这个对象的引用的类型却有很多
- instanceof
存在的条件:
- 有继承关系
- 子类重写父类方法
- 父类引用指向子类对象
注意事项:
- 多态是指方法的多态,属性没有多态
- 父类和子类,有联系
- 继承关系,方法需要重写,父类引用指向子类对象
静态方法的调用(不叫重写)
class A{
public static void test(){
System.out.println("A==>test()");
}
}
public class B extends A{
public static void test(){
System.out.println("B==>test()");
}
public static void main(String[] args) {
// 构造一个A类的对象
A a1 = new A();
a1.test();
// 父类引用指向了子类
A a2 = new B();
a2.test();
}
}
运行结果:
A==>test()
A==>test()
分析:静态方法的调用只和左边,即定义的数据类型有关
非静态方法的重写与调用
class A{
public void test(){
System.out.println("A==>test()");
}
}
public class B extends A{
// 子类重写了父类的方法
public void test(){
System.out.println("B==>test()");
}
public static void main(String[] args) {
// 构造一个A类的对象
A a1 = new A();
a1.test();
// A类型的变量实际接受B类型的对象
A a2 = new B();
a2.test();
}
}
运行结果:
A==>test()
B==>test()
分析:非静态方法的调用和左边和右边都有关
- 对象能否执行方法?得看指向这个对象的引用类中有没有这个方法,即父类指向子类,不能调用子类独有的方法
- 对象执行什么方法?得看右边对象实际的类型来决定
5.6
class A{
}
public class B extends A{
public static void main(String[] args) {
B bb = new B();
System.out.println(bb instanceof A);
}
}
运行结果:
true
6、static
“static方法就是没有this的方法。在static方法内部不能调用非静态方法,反过来是可以的。而且可以在没有创建任何对象的前提下,仅仅通过类本身来调用static方法。这实际上正是static方法的主要用途。”
用途:方便在没有创建对象的情况下来进行调用(方法/变量)。
- static方法
static方法一般称作静态方法,因为不依赖任何对象,所以不存在this。
在静态方法中不能访问类的非静态成员变量和非静态成员方法,因为非静态成员方法/变量都是必须依赖具体的对象才能够被调用。
- static变量
static变量也称作静态变量,静态变量和非静态变量的区别是:静态变量被所有的对象所共享,在内存中只有一个副本,它当且仅当在类初次加载时会被初始化。而非静态变量是对象所拥有的,在创建对象的时候被初始化,存在多个副本,各个对象拥有的副本互不影响。
static成员变量的初始化顺序按照定义的顺序进行初始化。
- static代码块
static关键字还有一个比较关键的作用就是 用来形成静态代码块以优化程序性能。static块可以置于类中的任何地方,类中可以有多个static块。在类初次被加载的时候,会按照static块的顺序来执行每个static块,并且只会执行一次。
因此,很多时候会将一些只需要进行一次的初始化操作都放在static代码块中进行。
注意
与C/C++中的static不同,Java中的static关键字不会影响到变量或者方法的作用域
在Java中能够影响到访问权限的只有private、public、protected(包括包访问权限)这几个关键字
在C/C++中static是可以作用域局部变量的,但是在Java中切记:static是**不允许用来修饰局部变量****
7、抽象类
// 抽象类, 抽象的抽象
public abstract class Action{
// 制定约束,让别人来实现
// 只有方法定义,没有方法的具体实现
public abstract void doSomething();
}
- 抽象类不能创建对象,即不能new,只能靠子类去实现,而它本身只是制定了约束
- 抽象类中可以写普通的方法
- 抽象方法必须在抽象类中,即如果一个类包含抽象方法,那么该类必须是抽象类。
- 抽象类中不一定包含抽象方法,但是有抽象方法的类必定是抽象类。
- 任何子类必须重写父类的抽象方法,或者声明自身为抽象类。
- 构造方法,类方法(用 static 修饰的方法)不能声明为抽象方法。
抽象类的构造函数
虽然抽象类不能被实例化,但可以有构造函数。由于抽象类的构造函数在实例化派生类之前发生,所以,可以在这个阶段初始化抽象类字段或执行其它与子类相关的代码。
8、接口
普通类:只有具体实现
抽象类:具体实现和规范(抽象方法)都有
接口:只有规范,专业的约束,约束和实现分离:面向接口编程
关键字:interface implements
- 接口中的所有方法的定义都是抽象的,即public abstract,可省略,属性都为public static final
- java不支持多继承,但是支持实现多接口,间接实现多继承
- 接口没有构造方法
interface A {
void say();
}
// 实现接口
public class Action implements A{
@Override
public void say() {
System.out.println("Hello World!");
}
public static void main(String[] args) {
new Action().say();
}
}
运行结果:
Hello World!
9、内部类(奇葩!)
首先说明本质:无限套娃
9.1 成员内部类
public class Outer{
int age = 11;
public void out(){
System.out.println("外部类的方法");
}
// 成员内部类
public class Inner{
public void in(){
System.out.println("内部类的方法");
}
}
public static void main(String[] args) {
// 正常创建对象的形式
Outer outer = new Outer();
// 调用成员内部类的方法
// 通过Outer的对象new一个Inner的对象,用Outer.Inner类型的引用接受
Outer.Inner in = outer.new Inner();
in.in();
}
}
9.2 局部内部类
public class Outer{
public void method(){
// 局部内部类
class Inner {
public void in(){
}
}
}
}
9.3 匿名内部类
interface User{
void say();
}
public class Outer{
public static void main(String[] args) {
new User(){
@Override
public void say() {
System.out.println("实现了接口的方法");
}
};
}
}