JAVA 笔记(上)

2021/5/7 22:27:12

本文主要是介绍JAVA 笔记(上),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

封装的步骤:

第一步:属性私有化
第二步:一个属性对外提供两个方法(set,get),外部程序只能通过SET方法修改,GET方法获取,!可以在SET方法中设立关卡来保护数据的安全性。

强调:set和get都是实例方法,不可以带static。
不带static的方法称为实例方法,实例方法的调用必须先new对象。
set方法和get方法有严格的格式要求:
set: public void setName(String name){
this.name=name;
}


get:: public String getName(){
            retuen name;
}

this和static

1.static
a.所有static修饰的都是类相关的,类级别的。
b.所有static修饰的,都是采用“类名.”的方式访问的。
c.static修饰的变量称为静态变量,修饰的方法称为静态方法。

变量的分类:
局部变量:存栈当中
实例变量:对象级别,堆内存当中,引用. 访问
静态变量:static修饰,类级别,方法区中 类名. 访问。但 引用. 也可以访问,但不建议。
![image.png](https://www.www.zyiz.net/i/ll/?i=img_convert/fd478406419279f43fe95b3ce48eb111.png#height=328&id=ogfbe&margin=[object Object]&name=image.png&originHeight=438&originWidth=427&originalType=binary&size=137866&status=done&style=stroke&width=320)
实例的,都是对象相关的,访问时采用“引用.”的方式访问,需要先new对象
实例相关的,必须先有对象,才能访问,可能会出现空指针异常。
静态的,都是类相关的,访问时采用“类名**.**”的方式访问。不需要new对象
不需要对象的参与即可访问,没有空指针异常的发生。


什么时候变量声明为实例,什么时候静态呢?
当一个类的所有对象的某个“属性值”不会随着对象的改变而变化的时候,建议将该属性定义为静态属性(或者说把这个变量定义为静态变量) 可以节省空间。


什么时候方法声明为实例,什么时候静态?
如果该方法中直接访问了实例变量,该方法必须是实例方法。


静态方法: 当方法体中需要直接访问当前对象 的实例变量 或者实例方法的时候,该方法必须定义为实例方法,
因为只有实例方法中才有 this,静态方法中不存在 this。
—方法描述的是动作,当所有的对象执行这个动作时,最终产生的影响是一样的,那么这个动作就不再属于某一个对象的动作了,可以将这个动作提升为类级别的动作,模板级别的动作。
----静态方法中不能直接访问实例方法和实例变量。

//实例方法

不同的客户购物,最终的效果都不同,另外在 shopping()方法中访问了
当前对象的实例变量 name,以及调用了实例方法 pay(),所以 shopping()方法不能定义为静态方法,必须声明为实例方法

public class Customer {
String name;
public Customer(String name){
this.name = name;
}
public void shopping(){
//直接访问当前对象的 name
System.out.println(name + "正在选购商品! ");
//继续让当前对象去支付
pay();
}
public void pay(){
System.out.println(name + "正在支付! ");
}
}

public class CustomerTest {
public static void main(String[] args) {
Customer jack = new Customer("jack");
jack.shopping();
Customer rose = new Customer("rose");
rose.shopping();
}
}
/*
工具类”当中的方法一般定义为静态方法,因为工具类就是为
了方便大家的使用,将方法定义为静态方法,比较方便调用,不需要创建对象,直接使用类名
就可以访问。请看以下工具类,为了简化“System.out.println();”代码而编写的工具类
*/
public class U {
public static void p(int data){
System.out.println(data);
}
public static void p(long data){
System.out.println(data);
}
public static void p(float data){
System.out.println(data);
}
public static void p(double data){
System.out.println(data);
}
public static void p(boolean data){
System.out.println(data);
}
public static void p(char data){
    System.out.println(data);
}
public static void p(String data){
System.out.println(data);
}
}

public class HelloWorld {
public static void main(String[] args) {
U.p("Hello World!");
U.p(true);
U.p(3.14);
U.p('A');
}
}

**总结:所有实例相关的,包括实例变量和实例方法,必须先创建对象,然后通过“引用”的方式去访问,
如果空引用访问实例相关的成员,必然会出现空指针异常。
实例方法会出现空指针异常,静态方法不会。


所有静态相关的,包括静态变量和静态方法,直接使用“类名”去访问。
虽然静态相关的成员也能使用“引用.”去访问,但这种方式并不被主张。
静态代码块
语法:**static{
java语句;
}
什么时候执行?
类加载时执行,在main方法执行之前执行,并且只执行一次。
自上而下依次执行。


2.this
定义:
1. this是一个变量,是一个引用。this保存当前对象的内存地址,指向自身。 所以,严格意义上来讲,this代表的就是“当前对象”。
this存储在堆内存中,对象的内部。
2.this只能使用在实例方法中,谁调用这个实例方法,this就是谁,所以this代表的是当前对象。
3.this.大部分情况下可以省略。
4.static方法中为什么不可以使用this?
因为static用类.访问,不需要对象访问,而this代表当前对象。
5.什么时候不可以省略?
区分实例变量与局部变量时不可以省略。
6.this()
通过当前构造方法去调用另一个本类的构造方法,可以使用this(实际参数列表)。
作用:代码复用。![image.png](https://www.www.zyiz.net/i/ll/?i=img_convert/41af4138db5d9a0a8067dad49d027714.png#height=293&id=JcfsW&margin=[object Object]&name=image.png&originHeight=390&originWidth=625&originalType=binary&size=205509&status=done&style=none&width=469)
对于this()的调用只能出现在构造方法的第一行。


继承

**定义:**在不同的类中也可能会有共同的特征和动作,可以把这些共同的特征和动作放在一个类中,让其它类共享。因此可以定义一个通用类,然后将其扩展为其它多个特定类,这些特定类继承通用类中的特征和动作。继承是 Java 中实现软件重用的重要手段,避免重复,易于维护。
**作用:**继承可以解决代码臃肿的问题。换句话说,继承解决了代码复用的问题(代码复用就是代码的重复利用) ,这是继承机制最基本的作用。
重要作用:继承之后才会衍生出方法的覆盖和多态机制。
**特性: **
① B类继承 A类,则称 A类为超类(superclass)、父类、基类, B类则称为子类(subclass)、派生类、扩展类。


② java 中的继承只支持单继承,不支持多继承, C++中支持多继承,这也是 java 体java 中不允许这样写代码: class B extends A,C{ }。


③ 虽然 java 中不支持多继承,但有的时候会产生间接继承的效果,例如: class C, class B extends A,也就是说, C 直接继承 B,其实 C 还间接继承 A。


④ java 中规定,子类继承父类,除构造方法不能继承外,剩下都可以继承。但是私有属性无法在子类中直接访问。(父类中private修饰的不能再子类中直接访问,可以通过间接的方式访问(get方法)。)


⑤ java 中的类没有显示的继承任何类,则默认继承 Object 类, Object 类是 java 语言Object 类型中所有的特征。


⑥ 继承也存在一些缺点,耦合度高,父类修改,子类受到牵连。
例如: CreditAccount 类继承 Account 类会导致它们之间的耦合度非常高, Account 类发生改变之后会马上影响到 CreditAccount 类。


子类继承父类之后,能使用子类对象调用父类方法么?
可以。
其实本质上,子类继承父类之后,是将父类继承过来的方法归自己所有了。实际上调用的也不是父类的方法,是他自己的方法!


实际开发中,满足什么条件的时候,可以使用继承?
凡是可以用“is a”能描述的,都可以继承。
eg: Cat is a Animal Dog is a Animal

方法覆盖:

方法覆盖与方法重载的区别?
方法重载
定义:当一个类中,如果功能相似,建议将名字定为一样的,这样代码美观,并且方便编程。


方法重载的三个条件:

        1. 在同一个类中
        1. 方法名相同
        1. 参数列表不同(个数,顺序,类型)


定义:父类中继承过来的方法已经不够用了,子类有必要将这个方法重新再写一遍,所以方法覆盖又被称为方法重写。当该方法被重写之后,子类对象一定会调用重写之后的方法 。
必要条件:① 方法覆盖发生在具有继承关系的父子类之间,这是首要条件;相同的返回值类型、相同的方法名、相同的形式参数列表
相同的返回值类型:
对于返回值类型是基本数据类型的来说,必须一致。
对于返回值类型是引用数据类型的来说,覆盖之后返回值的类型可以变得更小(意义不大)
③访问权限不能更低,可以更高。
** ④重写之后的方法不能比之前的方法抛出更多的异常,可以相同或更少。**
**注意事项: **
① 由于覆盖之后的方法与原方法一模一样,建议在开发的时候采用复制粘贴的方式,不建议手写,因为手写的时候非常容易出错,比如在 Object 类当中有             toString()方法,该方法中的 S 是大写的,在手写的时候很容易写成小写 tostring(),这个时候你会认为 toString()方法已经被覆盖了,但由于方法名不一          致,导致最终没有覆盖,这样就尴尬了;


–讲了多态就明白了。–
② 私有的方法不能被继承,所以不能被覆盖; ✔


③ 构造方法不能被继承,所以也不能被覆盖;✔


④ 方法覆盖只是和方法有关,和属性无关;✔


⑤ 静态方法不存在覆盖(不是静态方法不能覆盖,是静态方法覆盖意义不大,学习 ✔

多态

定义:它的前提是封装形成独立体,独立体之间存在继承关系,从而产生多态机制。多态是同一个行为具有多个不同表现形式或形态的能力。
多态就是“同一个行为”发生在“不同的对象上”会产生不同的效果。


小知识点:
![image.png](https://www.www.zyiz.net/i/ll/?i=img_convert/c3070ab064787547d4daf900675d4537.png#height=219&id=J5COS&margin=[object Object]&name=image.png&originHeight=292&originWidth=373&originalType=binary&size=34729&status=done&style=none&width=280)
java 中允许这样的两种语法出现,一种是向上转型( Upcasting),一种是向下转型(Downcasting),
向上转型是指 子类型转换为父类型,又被称为自动类型转换,


向下转型是指 父类型转换为子类型,又被称为强制类型转换。
****:无论是向上转型还是向下转型,两种类型之间必须要有 继承关系,没有继承关系情况下进行向上转型或向下转型的时候编译器都会报错。
eg: Animal a = new Cat();
a.catchMouse();
此代码会编译错误,因为“Animal a = newCat();”在编译的时候,编译器只知道 a 变量的数据类型是 Animal,也就是说它只会去Animal.class 字节码中查找 catchMouse()方法,结果没找到,自然“静态绑定”就失败了,编译没有通过。
就像以上描述的错误信息一样:在类型为 Animal 的变量 a 中找不到方法catchMouse()。
向上转型(子类型转换为父类型)

eg:Animal a = new Cat();
a.move();
分析: java程序分为编译阶段和运行阶段
编译阶段:对于编译器来说,编译器只知道a2的类型是Animal,所以编译器在检查语法的时候,会去Animal.class字节码文件中找move()方法,找到了,绑定上move()方法,编译通过,静态绑定成功。(编译阶段属于静态绑定。)
运行阶段:运行阶段时,实际上在堆内存中创建的java对象是Cat对象,所以move的时候,真正参与move的对象是一只猫,所以运行阶段会动态执行Cat对象的move()方法。这个过程属于运行阶段绑定。(运行阶段绑定属于动态绑定。)
多态表示多种形态:
编译的时候一种形态。
运行的时候一种形态。


向下转型:为了调用子类对象特有的方法(父类型转换为子类型)
Animal a = new Cat();
Cat c = (Cat)a; //将Animal类型强制转换为Cat类型。
代码修改后, 就可以正常运行。直接使用 a 引用是无法调用 catchMouse()方法的,因为这个方法属于子类 Cat中特有的行为,不是所有 Animal 动物都可以抓老鼠的,
要想让它去抓老鼠,就必须做向下转型(Downcasting),也就是使用强制类型转换将 Animal 类型的 a 引用转换成 Cat 类型的引用c(Cat c = (Cat)a;),使用 Cat 类型的 c 引用调用 catchMouse()方法。


instanceof 运算符 (在进行任何向下转型的操作之前,要使用 instanceof 进行判断):
为什么要用instanceof运算符?
因为向下转型有风险。
eg:
Animal a = new Bird();


Cat y = (Cat)a;
a.catchMouse():
//分析程序
编译阶段:编译器检测a这个引用是Animal类型,和Cat存在继承关系,所以可以向下转型。
运行阶段:会出错,因为堆内存中实际上创建的对象 是 Bird对象。拿Bird对象转换为Cat对象是不可以的,他俩不存在继承关系。
会出现异常:java.lang.ClassCastException:类型转换异常。 很重要。


空指针异常: java.lang.NullPointerException


** 知识点: ** 1.instanceof可以在运行阶段动态判断引用指向的对象的类型。
2.instanceof的语法:(引用 instanceof 类型)
3.instanceof运算符的结果只能是:true/false
4.c是一个引用,c变量保存了内存地址指向了堆内存中的对象。
假设(c instancof Cat)为true表示:
c引用指向的堆内存中的java对象是一个Cat。
假设(c instanceof Ca)为false表示:
c引用指向的堆内存中的java对象不是一个Cat。
eg:
Animal a = new Bird();
}
**多态的三个必要条件:① 继承
    ★:方法覆盖主要是说实例方法,静态方法不谈方法覆盖。


多态在开发中的作用:
1.**降低程序的耦合度,提高程序的扩展力。
public class Master{
public void feed(Dog d){}
public void feed(Cat c){}
}
以上代码的 Master和Cat,Dog的关系很紧密(耦合度高),导致扩展力很差。


public class Master{
public void feed(Pet pet){}
}
以上代码 Master和Cat,Dog的关系就脱离了(耦合度低),Master关注的是Pet类,提高了软件的扩展性。
一个软件开发原则:
七大原则最基本的原则:OCP(对扩展开放,对修改关闭)
目的:降低程序耦合度,提高程序扩展力。
要面向抽象编程,不建议面向具体编程。


覆盖遗留问题解答:
1.方法覆盖需要和多态机制联合起来使用才有意义。
没有多态机制的话,方法覆盖没什么意义,如果父类无法满足子类业务 需求时,子类完全可以定义一个全新方法。
2.静态方法存在方法覆盖么?
多态和对象相关,而静态方法的执行不需要对象,所以 一般情况下我们会说静态方法“不存在”方法覆盖。
![image.png](https://www.www.zyiz.net/i/ll/?i=img_convert/322a1a9c9bfd62b80cd2fa398ab09543.png#height=472&id=rBqW1&margin=[object Object]&name=image.png&originHeight=629&originWidth=1030&originalType=binary&size=481450&status=done&style=none&width=773)
3.私有方法不能覆盖 :记住就行。


**总结:**私有不能覆盖,静态不谈覆盖。
    

super


super与this的对比:

  • this表示当前对象
  • super表示的是当前对象的父类特征。(super是this指向的那个对象中的一块空间)


this:
1.this能出现在构造方法和实例方法中。
2.this的语法是:“this.”,“this()”.
3.this不能使用在静态方法中。
4.this.大部分情况下是可以省略的。
5.this.什么时候不可以省略呢?
在区分局部变量和实例变量的时候不可以省略。
6.this()只能出现在构造方法的第一行,通过当前的构造方法去调用“本类”中其他的构造方法
目的是:代码复用。
super:
1.super能出现在实例方法和构造方法中。
2.super的语法是:“super.”,“super()”.
3.super不能使用在静态方法中。
因为 super 代表了当前对象上的父类型特征,静态方法中没有 this,肯定也是不能使用 super 的。
4.super.大部分情况下是可以省略的。


5.super.什么时候不可以省略呢?
当父类中有该实例变量或方法,子类中又重新定义了同名的实例变量或方法,如果想在子类中访问父类的实例变量或方法, super. 不能省略。。
this.name:当前对象的name属性
super.name:当前对象的父类型特征中的name属性。
6.super()只能出现在构造方法的第一行,通过当前的构造方法去调用“父类”中的构造方法。
目的是:创建子类对象的时候,先初始化父类型特征。


7.super() :表示通过子类的构造方法调用父类的构造方法。 模拟现实世界里的场景:要想有儿子,先要有父亲。


8.当一个构造方法第一行: 既没有this()又没有super()的话,默认会有一个super();
表示通过当前子类的构造方法调用父类的无参构造方法。
所以必须保证父类的无参构造方法是存在的。
this()和super()不能共存,都只能在第一行。


9.无论如何折腾,父类的构造方法是一定会执行的。
10.super不是引用,super也不保存内存地址,super也不指向任何对象。 super知识代表当前对象内部的那一块父类型特征。


eg:

public class SuperTest {
    public static void main(String[] args) {
        new C(); //执行顺序 1-3-6-5-4 ,栈的原理:最后调用的,最先执行结束。 后进先出原则
    }
}

class A{
    public A() {
        //实际上这个地方也有一个super() 是老祖宗Object类的无参构造方法。
        System.out.println("A的无参数构造方法执行"); //1
    }
}

class B extends A{
    public B() {
        System.out.println("B的无参数构造方法执行"); //2
    }
    public B(String name){
        //默认有个super() 调用A
        System.out.println("B的有参数构造方法执行"); //3
    }
}

class C extends B{
    public C() {
        this("zhangsan");
        System.out.println("C的无参数构造方法执行"); //4
    }
    public C(String name){
        this("zhangsan",20);
        System.out.println("C的有参数构造执行(String)"); //5
    }
    public C(String name,int age){
        super(name);
        System.out.println("C的有参数构造方法执行(String,int)"); //6
    }
}


**super(实际参数列表):**通过当前的构造方法调用父类的构造方法,代码复用性增强了。
初始化对象的父类型特征。
![image.png](https://www.www.zyiz.net/i/ll/?i=img_convert/b242455ab21587e713de7554e62dc228.png#height=89&id=goxTb&margin=[object Object]&name=image.png&originHeight=118&originWidth=832&originalType=binary&size=130891&status=done&style=none&width=624)




super()的作用主要是:
第一,调用父类的构造方法,使用这个构造方法来给当前子类对象初始化父类型特征;
第二,代码复用。

进阶-面向对象

final关键字

定义:


1.采用 final 修饰的类不能被继承

//错误 不可以继承
final class A1 {
	public void test1() {}
}

class B1 extends A1 { 
	public void test2() {}
}

2.采用 final 修饰的方法不能被覆盖

class A1 {
public final void test1() {
}
}

class B1 extends A1 {
//覆盖父类的方法,改变其行为
//因为父类的方法是 final 修饰的,所以不能覆盖
public void test1() {
}
public void test2() {
}
}

3.采用 final 修饰的变量不能被修改,只能赋一次值。


4.final 修饰的变量必须显示初始化

//如果是 final 修饰的变量必须初始化
private static final long CARD_NO = 0L;
public static void main(String[] args) {
int i;
//局部变量必须初始化
//如果不使用可以不初始化
System.out.println(i);
}

5.如果修饰的引用,那么这个引用只能指向一个对象,也就是说这个引用不能再次赋值,但被指向的对象里的值是可以修改的
final Person p = new Person(30);
p = new Person(30); //✖,final修饰的引用不能再次赋值。
p.serAge(40);//✔
6.实例变量如果没有手动赋值的话,系统会赋默认值(实例变量在new对象(构造方法执行时)的时候赋默认值)。
但是final修饰的实例变量,系统不给赋默认值,要求程序员必须手动赋值。这个手动赋值,在变量后面赋值可以,在构造方法中赋值也可以。


7.static final联合修饰的变量称为“常量”,常量名建议全部大写,每个单词之间采用下划线连接。
static final String country = “中国”;
常量实际上和静态变量一样,区别在于:
常量的值不能变,常量和静态变量都是存储在方法区,并且都在类加载时初始化。
常量一般都是公开的,因为公开了你也改不了。
8.构造方法不能被 final 修饰

抽象类

类 --> 对象:实例化
对象 --> 类 :抽象
**定义:**类和类之间具有共同特征,将这些共同特征提取出来,形成的就是抽象类。


1.什么是抽象类?   
类和类之间具有共同的特征,将这些共同特征提取出来,形成的就是抽象类。
类本身也是不存在的,所以抽象类无法创建对象(无法实例化)。
抽象类属于引用数据类型。
3.抽象类怎么定义?
[修饰符列表] abstract class 类名{
类体;
}
4.抽象类是无法实例化的,无法创建对象的,所以抽象类是用来被子类继承的。
不可以。
6.抽象类的子类可以是抽象类。
7.抽象类无法实例化,但是抽象类有构造方法,这个构造方法是给子类使用的。
8.什么是抽象方法?
抽象方法表示没有实现的方法,没有方法体的方法。
eg:public abstract void dosome();
a.没有方法体,以分号结尾。
b.前面修饰符列表中没有abstract关键字。
9.如果一个类中含有抽象方法,那么这个类必须定义成抽象类
如果有一个方法为抽象的,那么此类必须为抽象的    
如果一个类是抽象的,并不要求具有抽象的方法
⭐10. 一个非抽象类继承抽象类,必须将抽象类中的抽象方法 实现/覆盖/重写 了。
一个抽象类继承抽象类,则不用。
11. 抽象的方法只需在抽象类中,提供声明,不需要实现,起到一个强制约束作用,要求子类必须实现。


面试题:java语言中凡是没有方法体的方法都是抽象方法。(✖)
Object类中就有很多都没有方法体,都是以分号结尾。调用了C++的底层代码。






  ![image.png](https://www.www.zyiz.net/i/ll/?i=img_convert/4b0d3fcf4d03944d5a541ac599f1a6e3.png#height=259&id=FQmCC&margin=[object Object]&name=image.png&originHeight=259&originWidth=700&originalType=binary&size=43658&status=done&style=none&width=700)
P338




接口

**定义:**接口我们可以看作是抽象类的一种特殊情况,在接口中只能定义抽象的方法和常量

  1. 接口是一种引用数据类型,编译之后也是一个class字节码文件
  2. 接口是完全抽象的。(抽象类是半抽象的。)或者也可以说接口是特殊的抽象类。
  3. 接口怎么定义?语法是什么?

[修饰符列表] interface 接口名{}

  1. 接口支持多继承,一个接口可以继承多个接口
  2. 接口中只包含两部分内容,一部分是:常量。一部分是:抽象方法。
  3. 接口中所有的元素都是public修饰的。
  4. 接口中的抽象方法定义时:public abstract修饰符可以省略

void addStudent(int id, String name); == public abstract void addStudent(int id, Stringname);

  1. 接口中的方法都是抽象方法,所以接口中的方法不能有方法体。
  2. 接口中的常量的 public static final 可以省略

double PI = 3.14; == public static final double PI = 3.14;

  1. 接口不能被实例化,接口中没有构造函数的概念


1.接口之间可以继承,但接口之间不能实现 ```java //接口可以继承 interface inter3 extends inter1 { public void method4(); }

//接口不能实现接口
//接口只能被类实现
interface inter4 implements inter2 { //接口不能实现接口
public void method3();
}

2.接口中的方法只能通过类来实现,通过implements 关键字<br />⭐3.如果一个非抽象类,实现了接口,那么必须将接口中所有的方法实现。<br />4.一个类可以实现多个接口 
```java
//实现多个接口,采用逗号隔开
//这样这个类就拥有了多种类型
//等同于现实中的多继承
//所以采用 java 中的接口可以实现多继承
//把接口粒度划分细了,主要使功能定义的含义更明确
//可以采用一个大的接口定义所有功能,替代多个小的接口,
//但这样定义功能不明确,粒度太粗了
class InterImpl implements Inter1, Inter2, Inter3 {
		****
}


5.extends和implements都存在的话,代码怎么写?
extends在前,implements在后。
6.使用接口,写代码时,可以使用多态(父类型引用指向子类型对象)。


接口在开发中的作用(解耦合):
理解:![image.png](https://www.www.zyiz.net/i/ll/?i=img_convert/ce8634eeee20c6a8d65faa8acd0fb11c.png#height=259&id=RlsFp&margin=[object Object]&name=image.png&originHeight=345&originWidth=1081&originalType=binary&size=356913&status=done&style=none&width=811)
1.扩展性好,可插拔。
2.面向接口编程,可以降低程序的耦合度,提高程序的扩展力,符合OCP开发原则。
3.接口的使用离不开多态机制,因为接口是抽象的无法创建对象,必须指向子类。(接口+多态才可以达到降低耦合度。)
4.接口可以解耦合,解开的是谁和谁的耦合?
任何一个接口都有调用者和实现者,
接口可以将调用者(顾客)和实现者(厨师)解耦合。
调用者面向接口调用,实现者面向接口编写实现。
5.进行大项目开发时,一般都是将项目分离成多模块,模块和模块之间衔接。降低耦合度。
接口的优点:

  • 采用接口明确的声明了它所能提供的服务
  • 解决了 Java 单继承的问题
  • 实现了可接插性(重要)

11

接口和抽象的区别

主要是语法上的区别,至于使用上的区别,在后期项目中体会学习。
1.抽象类是半抽象的,接口是完全抽象的。
2.抽象类中有构造方法,接口中没有构造方法。
3.接口和接口之间支持多继承,类和类之间只能单继承。
4.一个类可是实现多个接口,一个抽象类只能继承一个类(单继承)。
5.接口中只允许出现常量和抽象方法。


a) 接口描述了方法的特征,不给出实现,一方面解决 java 的单继承问题,实现了强大的可接插性
b) 抽象类提供了部分实现,抽象类是不能实例化的,抽象类的存在主要是可以把公共的代码移植到抽象类中
c) 面向接口编程,而不要面向具体编程(面向抽象编程,而不要面向具体编程)
d) 优先选择接口(因为继承抽象类后,此类将无法再继承,所以会丧失此类的灵活性)

类之间的关系(先不学)

  • 泛化关系:类和类之间的继承关系及接口与接口之间的继承关系
  • 实现关系:类对接口的实现
  • 关联关系:类与类之间的连接,一个类可以知道另一个类的属性和方法,在 java 语言中使用成员变量体现 。
  • 聚合关系:是关联关系的一种,是较强的关联关系,是整体和部分的关系,如:汽车和轮胎,它与关联关系不同,关联关系的类处在同一个层次上,而聚合关系的类                    处在不平等的层次上,一个代表整体,一个代表部分,在 java 语言中使用实例变量体现
  • 合成关系 :是关系的一种,比聚合关系强的关联关系,如:人和四肢,整体对象决定部分对象的生命周期,部分对象每一时刻只与一个对象发生合成关系,在 java                      语言中使用实例变量体现 。
  • 依赖关系:依赖关系是比关联关系弱的关系,在 java 语言中体现为返回值,参数,局部变量和静态方法调用 。


is a(继承)、has a(关联)、like a(实现)

  • is a:(继承)

Cat is a Animal(猫是一个动物)
   凡是能够满足is a的表示“继承关系”
   Cat extends Animal

  • has a:(关联)

I has a Pen(我有一支笔)
customer has a foodmenu
   凡是能够满足has a关系的表示“关联关系”
   关联关系通常以“属性”的形式存在。
   costomer{
    Foodmenu foodmenu;
   }

  • like a: (实现)

Cooker like a FoodMenu(厨师像一个菜单一样)
   凡是能够满足like a关系的表示“实现关系”
   实现关系通常是:类实现接口。
   A implements B

Object类

定义:
a) Object 类是所有 Java 类的根基类    
b) 如果在类的声明中未使用 extends 关键字指明其基类,则默认基类为 Object 类
Object类中的常用方法:
protected Object clone() //负责对象克隆
int hashCode() //获取对象哈希值的方法
boolean equals(object obj) //判断两个对象是否相等
String toString() //将对象转换成字符串形式
protected void finalize() //垃圾回收器负责调用的方法

toString()

定义:返回该对象的字符串表示。
通常 toString 方法会返回一个“以文本方式表示”此对象的字符串, Object 类的 toString 方法返回一个字符串,
该字符串由类名加标记@和此对象哈希码的无符号十六进制表示组成
源代码:Object 类 toString 源代码如下:        
public String toString(){
return getClass().getName() + ‘@’ + Integer.toHexString(hashCode())

eg:Person@757aef(类名@对象的内存地址转换为十六进制的形式)
作用:
1.通过调用这个方法可以将一个java对象转换成字符串表示形式。
2.建议所有子类都重写toString()方法。toString()方法应该是一个简洁的,详实的,已阅读的。
3.输出引用时,会自动调用该引用的toString()方法。-> System.out.println(引用);

==与euals方法

equals是判断:两个变量或者实例指向同一个内存空间的值是不是相同
(如果没有重写,equals比较的也是内存地址)
==是判断:两个变量或者实例是不是指向同一个内存空间
通俗的讲:==是判断两个人是不是住在同一个地址,而equals是判断同一个地址里住的人是不是同一个。

//实际上String也是一个类,不属于基本数据类型
//既然String是一个类,那么一定存在构造方法。
//String类中 已经重写了euqals()方法。⭐⭐⭐

		int a=10;
        int b=10;
        String str1=new String("justice");
        String str2=new String("justice");
        String str3;
        str3=str1;
   		
		//a和b都是基本数据类型,变量存储值,所以==为true,基本数据类型无equals方法(没有意义)
		System.out.println(a==b);	
		
		//str1和str2都是String类型,属于引用类型,变量存储地址,所以==为false,equals为true
		System.out.println(str1==str2);
        System.out.println(str1.equals(str2));
        
        //创建str3的时候,str3指向了str1,所以str1和str3的指向同一个地址,存储的数据自然相同,所以均为true
        System.out.println(str1==str3);
        System.out.println(str1.equals(str3));
    }

源代码:
public boolean euqals(object obj){
return (thisobj);

**作用:**1.判断两个对象是否相等。
2.根据需求选择equals()方法;
**总结: 1.**JAVA中什么类型的数据可以使用"
"判断?
Java中基本数据类型比较是否相等,使用==。
2.JAVA中什么类型的数据需要使用equals()判断?
java中所有的引用数据类型统一使用equals()方法来判断是否相等。


重写toString()方法和equals()方法例题:(P373)

finalize (了解)

**定义:**垃圾回收器(Garbage Collection),也叫 GC
**源码:**protected void finalize() throws Throwable()
这个方法只有一个方法体,里面没有代码。


**特点:**1.当对象不再被程序使用时,垃圾回收器将会将其回收,不需要程序员手动调用。只需要将其重写,
将来自动会有程序来调用。
2.垃圾回收是在后台运行的,我们无法命令垃圾回收器马上回收资源,
但是我们可以告诉他,尽快回收资源(System.gc 和Runtime.getRuntime().gc())
3.垃圾回收器在回收某个对象的时候,首先会调用该对象的 finalize 方法
4.GC 主要针对堆内存
5.单例模式的缺点

包和 import

1.包(package):

**定义:**package是java中的包机制,包其实就是目录,特别是项目比较大, java 文件特别多的情况下,
我们应该分目录管理,在 java中称为分包管理,包名称通常采用小写
**作用:**为了方便程序的管理,不同功能的类分别存放在不同的包下。(按照功能划分的,不同的软件包具有不同的功能。)


**知识点:**1.包名最好采用小写字母
2.包的命名有规则,不能重复,一般采用公司网站的逆序(因为公司域名具有全球唯一性。)。
如: package com.bjpowernode.项目名称.模块名称.功能名
package com.bjpowernode.exam
3.package 必须放到 所有语句的第一行,注释除外。

2.import

什么时候用?
当A类中使用B类,
A类和B类都在同一个包下,不需要import。
A类和B类不在一个包下,需要使用import。
怎么用?
import语句只能出现在package语句之下,class之上。
import还可以使用 import xx.xx.*; 表示导入该包下的所有类。

3.JDK常用开发包

1.java.lang,此包 Java 语言标准包,使用此包中的内容无需 import 引入,自动导入。
2.java.sql,提供了 JDBC 接口类
3.java.util,提供了常用工具类
4.java.io,提供了各种输入输出流


访问控制权限

**定义:**java 访问级别修饰符主要包括: private protected 和 public,可以限定其他类对该类、属性和方法的使用权限。


知识点:
1. ⭐:以上对类和接口的修饰只有: public 和 default, 内部类除外
default就是什么都不写,写上语法错误。
![](https://www.www.zyiz.net/i/ll/?i=img_convert/be6c28f9efde7a671291bc5215878a59.png#height=242&id=u42400f63&margin=[object Object]&originHeight=322&originWidth=1106&originalType=binary&size=47109&status=done&style=none&width=830)
2.private 私有的,只能在本类中访问,
public 公共的,在哪都可以访问。

内部类

**定义:**在一个类的内部定义的类,称为内部类。
内部类的分类:静态内部类(类似于静态变量)
实例内部类(类似于实例变量)
局部内部类(类似于局部变量)
使用内部类编写的代码,可读性很差,能不用就别用。

匿名内部类

定义:是局部内部类的一种,因为这个类没有名字,所以叫匿名内部类。

public static void main(String[] args){
	MyMath m1 = new Mymath();
    m1.mySum(new ComputeImpl(),1,2);
    
    //用匿名内部类改写以上代码,可以不写实现类,不建议使用!代码太乱,可读性差,无法重复使用。
    m1.mySum(new Compute(){
		public int sum(int a,int b){
    	return a+b;
    }},1,2);
   
}

interface Compute{
	int sum(int a,int b);
}
class ComputeImpl implements Compute{
	public int sum(int a,int b){
    	return a+b;
    }
}
public class MyMath{
	public void mySum(Compute c,int a,int b){
    	sout(c.sum(a,b));
    }
}

进阶-数组

1.数组概要

**定义:**数组是一种引用数据类型。
内存中存储示意图:
![](https://www.www.zyiz.net/i/ll/?i=img_convert/7f2e4a105b75da9d10c35fd7bd39133a.png#height=192&id=ud18853e5&margin=[object Object]&originHeight=384&originWidth=254&originalType=binary&size=14152&status=done&style=none&width=127)
**知识点:**1.数组是一组数据的集合。
2.数组作为一种引用类型,在堆内存中分配,父类是object。
3.数组元素的类型可以是基本类型,也可以是引用类型,但同一个数组只能是同一种类型。
4.数组作为对象。数组中的元素作为对象的属性,除此之外数组还包括一个成员属性length,
length表示数组的长度。
5.数组的长度在数组创建之后就确定了,就无法再修改了。
6.数组元素是有下标的,下标从0开始,也就是第一个元素的下标为0,最后一个元素的下标为n-1,
我们可以通过数组的下标来访问数组的元素。
7.数据当中如果存储的是“Java对象”的话,实际上存储的是对象的“引用(内存地址)”。
8.数组在内存中存储的时候,数组中的元素内存地址是连续(每一个元素都是有规则的挨着排列)的,
这是数组存储元素的特点,数组实际上是一种简单的数据结构。
9.数组中的第一个元素的内存地址就是整个数组对象的内存地址。
因为数组中的内存地址是连续的,有了第一个就能得到后面的。
10.数组的优缺点:
优点:
查询/查找/检索某个下标上的元素时效率极高,可以说是查询效率最高的一个数据结构。
why?
第一:每一个元素的内存地址在空间存储上是连续的。
第二:每一个元素的类型相同,所以占用的空间大小一样。
第三:知道第一个元素内存地址,知道每一个元素占用空间的大小,又知道下标,所以通过一个数学表达式就可以计算出某个下标上的元素的内存地址。直接通过地址定位元素。
所以数组的检索效率是最高的。
数组中存储100个元素和存储100W个元素,在元素查询/检索方面,效率是相同的,
因为数组中元素查找的时候不会一个一个找,是通过数学表达式计算出来的。
缺点:
第一:为了保证数组中每个元素的内存地址连续,所以在数组上随机删除或者增加元素的时候,效率较低,因为随机增删元素会涉及到后面元素统一向前或者向后位移的操作。
⭐:对于数组中最后一个元素的增删,是没有效率影响的。
第二:数组不能存储大数据量,why?
因为很难在内存空间上找到一块特别大的连续的内存空间。

2.一维数组的声明和使用

数组的声明:

**格式:**1.数组元素的类型[] 变量名称; (常用)
eg: int[] a;
int[] a,b,c;
Student[] stu;
2.数组元素的类型 变量名称[]

数组的初始化:

静态初始化:
int[] array = {100,200,300,400};
动态初始化:
int[] array = new int[5]; //这里的5表示初始化一个长度为5的int类型数组,每个元素默认为0.
String[] nmaes = new String[6]; //这里的6表示初始化一个长度为6的Stirng类型数组,每个元素默认为null.
什么时候采用静态初始化?什么时候采用动态初始化?
当你创建数组的时候,已知数组中存储哪些元素,采用静态初始化。
当你创建数组的时候,不确定数组中存储哪些元素,采用动态初始化,预先分配内存空间。

一维数组的遍历:


	


这篇关于JAVA 笔记(上)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程