Java基础总结篇(上)

前言

大一的学习生涯已经过了大半学期了,对于所学的java知识也未曾有过整理,借着周末时间整理一下上半学期所学的知识点,一方面可以加深下记忆,一方面忘记了也方便翻阅查找。

java基础概括图

ce528fe0e666908659cf818a09f394ba.jpg

Java概述

java发展概述

Java由SUN公司研发,SUN 被 Oracle 收购
Java 由1995年发布,正式版本由1996年1月发布(jdk1.0)
Java之父: James Gosling

java体系

  1. javaSE,标准版,各应用平台的基础,桌面开发和低端商务应用的解决方案。
  2. javaEE,企业版,以企业为环境而开发应用程序的解决方案。
  3. javaME,微型版,致力于消费产品和嵌入式设备的最佳方案。

java可以做什么

  1. 开发桌面应用程序。
  2. 开发面向Internet的web应用程序。
  3. 提供各行业的解决方案。
  4. 开发android手机应用程序。

java的特性

  1. 简单易学: Java语言的语法与C语言和C++语言很接近,使得大多数程序员很容易学习和使用Java。
  2. 面向对象: Java语言支持封装、继承、多态,面对对象编程,让程序的耦合度更低,内聚性更高。
  3. 跨平台型:Java语言编写的程序可以运行在各种平台上,也就是说同一段程序既可以在Windows操作系统上运行,也可以在Linx操作系统上运行。
  4. 解释型:Java程序在Java平台上被编译为字节码格式,然后可以在实现这个Java平台的任何系统的解释器中运行。
  5. 多线程: Java语言是支持多线程的。所谓多线程可以简单理解为程序中有多个任务可以并发执行,这样可以在很大程度上提高程序的执行效率。
  6. 健壮型: Java的强类型机制、异常处理、垃圾的自动收集等是Java程序健壮性的重要保证。对指针的丢弃是Java的明智选择。
  7. 可靠安全: Java语言经常被用在网络环境中,为了增强安全性,Java语言提供了防止恶意代码攻击的安全机制(数组边界检查和bytecode校验等)。

JDK &JRE

JDK:(Java Development Kit Java开发工具包),JDK是提供给Java开发人员使用的,其中包含了java的开发工具,也包括了JRE。其中的开发工具:编译工具(javac.exe) 打包工具(jar.exe)、执行工具(java.exe)等

JRE:(Java Runtime Environment Java运行环境) ,包括Java虚拟机(JVM Java Virtual Machine)和Java程序所需的核心类库等,如果想要运行一个开发好的Java程序,计算机中只需要安装JRE即可。

Win10下 Java环境变量配置

https://jason.langke01.cn/index.php/archives/31.html 文章单独讲解环境变量配置及JDK下载

java应用程序的运行机制

先编译(.class),在解释运行。

java程序开发的三个步骤

  1. 编写源程序,java源代码文件。
  2. 编译源程序,编译器编译编译成java字节码文件。
  3. 运行,java虚拟机(JVM)。

java是分两部分的:一个是编译,一个是运行

javac:负责的是编译的部分,当执行javac时,会启动java的编译器程序。对指定扩展名的.java文件进行编译。生成了jvm可以识别的字节码文件。也就是class文件,也就是java的运行程序。

java:负责运行的部分.会启动jvm.加载运行时所需的类库,并对class文件进行执行.

一个文件要被执行,必须要有一个执行的起始点,这个起始点就是main函数.

开发java应用的要点

  1. 一个源文件中只能有一个public修饰的类,其他类个数不限。
  2. 一个源文件有n个类时,编译结果的class文件就有n个。
  3. 源文件的名字必须和public修饰的类名相同。
  4. java语言中单词拼写大小写严格区分。
  5. main方法入口。
  6. 每一句以分号(;)结束。

Java文档注释

//单行注释

/*
多行注释:不能嵌套
*/

/**
文档注释: 可以通过 javadoc -d mydoc -author -version HelloWorld.java 命令生成说明文档
*/

开发工具:

  1. Eclipse 官网下载地址:https://www.eclipse.org/downloads/
  2. MyEclipse 官网下载地址:https://www.myeclipsecn.com/
  3. IntelliJ IDEA 官网下载地址:https://www.jetbrains.com/idea/

java语法基础

标识符

凡是自己命名的地方都叫标识符。 如: 包名、类名、接口名、方法名、变量名、常量名

关键字

Java赋予了特殊含义的单词。

命名的规则

  1. 可使用 字母 A-Z a-z 数字 0-9 特殊字符 下划线 “_” 和 美元符 “$”
  2. 数字不能开头
  3. 其中不能包含空格
  4. 不能使用关键字和保留字,但是可以包含关键字和保留字
  5. Java严格区分大小写,但是长度无限制。

命名的规范

  1. 包名: 所有字母都小写。 如: abcd
  2. 类名、接口名:若出现多个单词,每个单词首字母都大写。如: AaaBbbCcc
  3. 方法名、变量名: 若出现多个单词,第一个单词的首字母小写,其余单词首字母都大写。如: aaaBbbCcc
  4. 常量名: 所有字母都大写,每个单词之间以 “_” 分隔。 如: AAA_BBB_CCC

变量

  1. 变量的格式: 数据类型 变量名 = 值;
    //声明一个变量
    数据类型 变量名; 如: int num;

    //为变量赋值
    变量名 = 值; 如: num = 10;

    //声明一个变量并赋值
    int num = 10;

  2. 变量的概念:
    ①在内存中开辟一块内存空间
    ②该空间有名称(变量名)有类型(数据类型)
    ③变量可以在指定的范围内不断的变化
  3. 变量的注意:
    ①作用域:从变量定义的位置开始,到该变量所在的那对大括号结束
    ②局部变量在使用前必须赋初始值
    ③先声明,后使用

数据类型

  1. 基本数据类型
类型                                            字节数             二进制位数
byte (字节型)                                   1                   8
short(短整型)     char  (字符型)                2                   16
int  (整型)       float  (单精度浮点数)          4                   32
long (长整型)      double (双精度浮点数)          8                   64
布尔型:boolean      true    false

2.引用数据类型

|—类(class) —————- String 字符串
|—接口(interface)
|—数组([ ])

基本数据类型之间的转换

  1. 自动类型转换:范围小→范围大

    byte→short→int→long→float→double;
    char→int→long→float→double

  2. 强制类型转换:范围大→范围小

    需要加强制转换符

转义字符

\n 换行 \r 回车 \t 水平制表 ‘ 单引号 ” 双引号 \斜杠

运算符

算术运算符:+ 、 – 、 * 、 / 、 % 、 ++ 、 —

赋值运算符:= 、 += 、 -= 、 *= 、 /= 、 %=

关系运算符:> 、 < 、 >= 、 <= 、 == 、 !=

逻辑运算符:! 、 & (只要有一个false 最终结果就是false)

| (但凡有一个true 最终结果就是true)

^ (如果两边一样 最终结果为false 如果两边不同 最终结果为true)

&&(如果第一个是false 那第二个不执行 最终结果是false)

||(如果第一个表达式的结果是true 那第二个表达式 就不去计算了 ,最终结果是true)

位运算符: ~ 、 >> 、 << 、 >>>

字符串连接运算符:+

三目运算符:X ? Y :Z
X为boolean类型表达式,先计算x的值,若为true,整个三目运算的结果为表达式Y的值,否则整个运算结果为表达式Z的值

程序流程控制

结构化程序的三种结构:

顺序、选择(分支)、循环

条件判断:

        if(条件表达式){
            //当条件表达式结果为 true 时,需要执行的语句           
        }

        if(条件表达式){
            //当条件表达式结果为 true 时,需要执行的语句           
        }else{
            //当条件表达式结果为 false 时,需要执行的语句           
        }

        if(条件表达式1){
            //当条件表达式1 结果为 true 时,需要执行的语句           
        }else if(条件表达式2){
            //当条件表达式2 结果为 true 时,需要执行的语句           
        }else if(条件表达式3){
            //当条件表达式3 结果为 true 时,需要执行的语句
        }
        ……
        else{
            //当上述条件表达式结果都为 false 时,需要执行的语句           
        }

        注意:
            ①当某个条件表达式结果为true, 执行相应的语句,其他 else if 将不再执行
            ②if-else 语句可以嵌套的
选择结构:

        switch(表达式){
            case 值1 :
                //执行的语句
                break;
            case 值2 :
                //执行的语句
                //break;
            case 值3 :
                //执行的语句
                break;
            ……
            default :
                //执行的语句
                break;           
        }

         //需求:若一个数大于2 小于5  打印 “2-5”
         int i = 2;
         switch(i){
             case 1:
                 System.out.println("一");
                 break;
             case 2:
             case 3:   
             case 4:                           
             case 5:
                 System.out.println("2-5");
                 break;                                   
         }

    注意:
        1、表达式必须是int、byte、char、short、enmu、String类型
        2、constN必须是常量或者finall变量,不能是范围
        3、所有的case语句的值不能相同,否则编译会报错
        4、default可要可不要
        5、break用来执行完一个分支后使程序跳出switch语句块,否则会一直会执行下去。
循环结构:

        for ([循环变量初始值设定]; [循环条件判断]; [改变循环变量的值]){
                循环体
        }

     注意:
         1、表达式2一般不可以省略,否则死循环
         2、表达式3可以省略,但是在循环体中必须有语句修改变量,以使表达式2在某一时刻为false结束循环。
         3、若同时省略表达式1,表表达式3,则相当于while(表达式2)语句
         4、三个表达式均省略 即for(;;)语句,此时相当于while(true)语句
         5、表达式1、表达式3可以是逗号表达式,以使循环变量值在修改时可以对其它变量赋值

        while( 条件表达式语句){
             循环体语句;
        }

        [初始条件]
        do{
             循环体;
             [迭代]
        }while( 循环条件判断); 

     注意:
         1、当第一次执行时,若表达式=false时,则while语句不执行,而do/while语句执行一次后面的语句
         2、一定要切记在switch循环中,如果没有break跳出语句,每一个case都要执行一遍,在计算最终结果。

嵌套循环: 一个循环充当了另一个循环的循环体

    打印100以内的质数:
    boolean flag = true;
    for(int i = 2; i <= 100; i++){
        for(int j = 2; j < i; j++){
            if(i % j == 0){
                flag = false;
                break;
            }
        }
        if(flag){
            System.out.println(i);   
        }
        flag = true;
    }

特殊流程控制语句:结束多层for循环

    label:for(int i = 0; i < 100; i++){
        for(int j = 0; j < 100; j++){
            if(j == 13){
                System.out.println(j);
                break label;
            }
        }
    }
break和continue区别:

    break: 结束“当前”循环 。当用于switch-case语句时,用于结束当前 switch-case 语句
    continue:  结束“当次”循环
    注意:if外有循环可以用break、continue,单纯if不可以用。


if和switch的区别:

    if可以判断范围,也可以判断一个值
    switch只能判断指定的值

    若只判断指定的值,则使用switch语句,效率快
    if判断范围,对数据判断灵活,自身的格式也比较灵活


while 和 do-while 的区别?
    while : 先判断循环条件,再执行循环体
    do-while : 先执行循环体,再判断循环条件。(至少执行一次)   

方法的声明和使用

方法:也叫函数,是一个功能的定义。是一个类中最基本的功能单元

//需求: 计算一个数 * 2 + 1 的结果
int a = 10;
System.out.println(a * 2 + 1);

a = 5;
System.out.println(a * 2 + 1);

a = 8;
System.out.println(a * 2 + 1);


1.为什么使用方法?  

     减少重复代码,提供代码复用性

     使用方法将功能提炼出来

     写在类内

2.声明格式

    [修饰符] 返回值类型 方法名([形式参数列表]){

            程序代码;

            [return 返回值;]

    }

 注意:
     1、“返回值类型”与 “返回值”的数据类型需要保持一致

     2、调用方法通过方法名和参数列表,注意方法名和参数列表(参数的个数、参数的类型)必须一致

     3、若声明了“返回值类型”说明该方法运行后有结果,若调用者需要用到该结果可以声明同类型变量接收。

     4、方法中只能调用方法,不能声明其他方法

     5、若方法运行结束后,不需要返回任何结果给调用者时,方法“返回值类型”处声明为 void
        void : 表示没有返回值


3. 声明方法的两点明确

    1、方法是否需要返回结果给调用者
       明确是否需要返回值类型,返回值类型是什么

    2、方法是否有未知的数据参与运算
       明确是否需要参数列表,需要几个
     

跨类调用方法:

通过“类名.方法名" 方式调用。 (暂时使用static修饰的方法为例)   

return

1. 将数据返回给调用者,除了void外,return后必须跟着返回值,只能返回一个。

2. 终止方法的执行,返回数据类型必须是void,return后不能添加数据。

3. 当return结束方法的时候,要让其后面的代码有可能被执行到。

4. 一个方法里可以有多个return,在void里不能有返回值,其他的必须有返回值。 

重载overload

1、在一个类中,方法名字相同,参数类型不同。

   参数类型不同:个数、数据类型、顺序。

注意:

    1、重载和返回值类型,修饰符没有任何关系。

    2、参数变量名修改也不能够重载


public void show(char c, int a){}

public void show(int a, char c){}

public void show(int a, char c, double d){}

public void show(String str, int a){}

public void shows(char c, int a){}

递归

  1. 有返回值

  2. 有参数

  3. 能够有跳出循环的控制语句

  4. 自己调用自己

面向对象编程

特点:

将复杂的事情简单化。

面向对象将以前的过程中的执行者,变成了指挥者。

面向对象这种思想是符合现在人们思考习惯的一种思想。

面向对象和面向过程

 1. 面向对象:是以具体的事物为单位,考虑的是它的特征(属性)和行为(方法)。
    
 2. 面向过程:是以具体的流程为单位,考虑功能的实现。

(理解)把大象装冰箱一共分几步?
    ①打开冰箱   ②把大象装进去(存储大象)  ③关闭冰箱

    如何使用面向对象思想思考上述问题呢?

    人{

        拉(冰箱){
            冰箱.打开()   
        }

        指挥(动物){
            动物.进入()   
        }

        推(冰箱){
            冰箱.关闭()
        }
    }


    冰箱{

        打开(){}

        存储(){}

        关闭(){}

    }


    大象{
        进入(){}
    }

    猴{
        进入(){}
    }

    面向对象更加注重前期的设计

        1.就是对类的设计
        2.设计类就是设计类的成员:属性  &  方法


    面向对象:将现实生活中一类事物的共性内容进行提取,抽象成相应Java类,用Java中类对其进行描述
    现实生活中的事物:  小猫   小狗  大象
    共性内容: 名称   性别   年龄    吃饭的功能    睡觉的功能

    class Animal{
        //属性
        String name;
        char gender;
        int age;

        //方法-行为   
        public void eat(){
            System.out.println("吃饭");
        }

        public void sleep(){
            System.out.println("睡觉");
        }

    }

    若需要具体到某一个事物,通过  new 关键字创建对象

        Animal a1 = new Animal(); //
        a1.name = "大象";
        a1.gender = '男';
        a1.age = 2;

        a1.eat();
        a1.sleep();

        System.out.println(a1.name + "," + a1.age);

类和对象

1、对象:是一个实实在在的个体

   类:对现实生活中一类事物的描述,抽象的

2、类和对象的关系:

   类是对象的模板/抽象化的概念,对象是类的实例。

3、创建类和对象

    类:

    特征:全局变量/属性/成员变量

    动作:方法

    对象:

    类名 对象名=new 类名()

    注意:一个类可以创建多个对象,,每个对象之间没有关系。

成员变量和局部变量的区别:

1:成员变量直接定义在类中。

  局部变量定义在方法中,参数上,语句中。

2:成员变量在这个类中有效。

 局部变量只在自己所属的大括号内有效,大括号结束,局部变量失去作用域。

3:成员变量存在于堆内存中,随着对象的产生而存在,消失而消失。

 局部变量存在于栈内存中,随着所属区域的运行而存在,结束而释放。

内存管理:

分配: JVM自动为其分配内存空间

释放:JVM通过垃圾回收机制自动的释放内存空间


垃圾回收机制: 将内存中的垃圾对象释放

垃圾对象:不再被任何引用指向的对象

Person p = new Person();

p  = null;

System.gc(); //通知垃圾回收机制可以释放内存,但是并不能保证立即释放,加快释放。

构造函数:

属性
方法
构造器

1. 构造器的格式

    访问控制修饰符  类名(参数列表){
        //初始化语句
    }

2. 构造器的作用
    ①创建对象
    ②为对象进行初始化


3. 构造器的注意:
    ①构造器的名称必须与类名一致!
    ②若一个类中没有显示提供任何构造器,系统会自动提供一个默认无参构造器
    public Person(){}
    ③若一个类中显示的提供了任何构造器,系统默认构造器将不再提供
    ④构造器只能调用一次,并且是在创建对象时调用

4. 构造器的重载
    ①构造器的名称必须相同
    ②构造器的参数列表必须不同(参数的个数、参数的类型)

5. 为属性赋初始值的方式
    ①使用默认赋值
    ②直接显示赋值
    ③构造器
    顺序:①②③

    class Person{
        private String name;
        private int age;
        private char gender;

        public Person(){
            cry();   
        }

        public Person(String name){
            this.name = name;
        }

        public Person(String name, int age){
            this(name);
            this.age = age;
        }

        public Person(String name, int age, char gender){
            this(name, age);
            this.gender = gender;
        }

        public void setName(String name){
            this.name = name;//可以区分局部变量和成员变量
        }

        public void cry(){
            System.out.println("哭");   
        }
    }


    Person p = new Person("张三");
    //p.cry();

    Person p1 = new Person();
    //p1.cry();


“Person p = new Person();”

创建一个对象都在内存中做了什么事情?

    1:先将硬盘上指定位置的Person.class文件加载进内存。

    2:执行main方法时,在栈内存中开辟了main方法的空间(压栈-进栈),然后在main方法的栈区分配了一个变量p。

    3:在堆内存中开辟一个实体空间,分配了一个内存首地址值。new

    4:在该实体空间中进行属性的空间分配,并进行了默认初始化。

    5:对空间中的属性进行显示初始化。

    6:进行实体的构造代码块初始化。

    7:调用该实体对应的构造函数,进行构造函数初始化。()

    8:将首地址赋值给p ,p变量就引用了该实体。(指向了该对象)

This

代表对象,就是所在函数所属对象的引用。

this到底代表什么呢?哪个对象调用了this所在的函数,this就代表哪个对象,就是哪个对象的引用。

开发时,什么时候使用this呢?

在定义功能时,如果该功能内部使用到了调用该功能的对象,这时就用this来表示这个对象。

this 还可以用于构造函数间的调用。

调用格式:this(实际参数);

    this对象后面跟上 . 调用的是成员属性和成员方法(一般方法);

    this对象后面跟上 () 调用的是本类中的对应参数的构造函数。

注意:用this调用构造函数,必须定义在构造函数的第一行。因为构造函数是用于初始化的,所以初始化动作一定要执行。否则编译失败。

static

关键字,是一个修饰符,用于修饰成员(成员变量和成员函数)。

    特点:

    1、static变量

     按照是否静态的对类成员变量进行分类可分两种:一种是被static修饰的变量,叫静态变量或类变量;另一种是没有被static修饰的变量,叫实例变量。两者的区别是:

     对于静态变量在内存中只有一个拷贝(节省内存),JVM只为静态分配一次内存,在加载类的过程中完成静态变量的内存分配,可用类名直接访问(方便),当然也可以通过对象来访问(但是这是不推荐的)。

     对于实例变量,没创建一个实例,就会为实例变量分配一次内存,实例变量可以在内存中有多个拷贝,互不影响(灵活)。

    2、静态方法

     静态方法可以直接通过类名调用,任何的实例也都可以调用,因此静态方法中不能用this和super关键字,
      不能直接访问所属类的实例变量和实例方法(就是不带static的成员变量和成员成员方法)只能访问所属类的静态成员变量和成员方法。
      因为实例成员与特定的对象关联!这个需要去理解,想明白其中的道理,不是记忆!!!
     因为static方法独立于任何实例,因此static方法必须被实现,而不能是抽象的abstract。

    3、static代码块

     static代码块也叫静态代码块,是在类中独立于类成员的static语句块,可以有多个,位置可以随便放,它不在任何的方法体内,JVM加载类时会执行这些静态的代码块,如果static代码块有多个,JVM将按照它们在类中出现的先后顺序依次执行它们,每个代码块只会被执行一次。

    4、static和final一块用表示什么

    static final用来修饰成员变量和成员方法,可简单理解为"全局常量"!

    对于变量,表示一旦给值就不可修改,并且通过类名可以访问。

    对于方法,表示不可覆盖,并且可以通过类名直接访问。

    备注:

    1,有些数据是对象特有的数据,是不可以被静态修饰的。因为那样的话,特有数据会变成对象的共享数据。这样对事物的描述就出了问题。所以,在定义静态时,必须要明确,这个数据是否是被对象所共享的。

    2,静态方法只能访问静态成员,不可以访问非静态成员。

    (这句话是针对同一个类环境下的,比如说,一个类有多个成员(属性,方法,字段),静态方法A,那么可以访问同类名下其他静态成员,你如果访问非静态成员就不行)

    因为静态方法加载时,优先于对象存在,所以没有办法访问对象中的成员。

    3,静态方法中不能使用this,super关键字。

    因为this代表对象,而静态在时,有可能没有对象,所以this无法使用。

    4,主函数是静态的。

成员变量和静态变量的区别:

    1,成员变量所属于对象。所以也称为实例变量。

    静态变量所属于类。所以也称为类变量。

    2,成员变量存在于堆内存中。

    静态变量存在于方法区中。

    3,成员变量随着对象创建而存在。随着对象被回收而消失。

    静态变量随着类的加载而存在。随着类的消失而消失。

    4,成员变量只能被对象所调用 。

    静态变量可以被对象调用,也可以被类名调用。

    所以,成员变量可以称为对象的特有数据,静态变量称为对象的共享数据。

    静态代码块:就是一个有静态关键字标示的一个代码块区域。定义在类中。

    作用:可以完成类的初始化。静态代码块随着类的加载而执行,而且只执行一次(new 多个对象就只执行一次)。如果和主函数在同一类中,优先于主函数执行。

final

    根据程序上下文环境,Java关键字final有"这是无法改变的"或者"终态的"含义,它可以修饰非抽象类、非抽象类成员方法和变量。

    你可能出于两种理解而需要阻止改变、设计或效率。

        final类不能被继承,没有子类,final类中的方法默认是final的。

        final方法不能被子类的方法覆盖,但可以被继承。

        final成员变量表示常量,只能被赋值一次,赋值后值不再改变。

        final不能用于修饰构造方法。

    注意:父类的private成员方法是不能被子类方法覆盖的,因此private类型的方法默认是final类型的。

        1、final类

            final类不能被继承,因此final类的成员方法没有机会被覆盖,默认都是final的。
            在设计类时候,如果这个类不需要有子类,类的实现细节不允许改变,并且确信这个类不会载被扩展,那么就设计为final类。

        2、final方法

            如果一个类不允许其子类覆盖某个方法,则可以把这个方法声明为final方法。

            使用final方法的原因有二:

            第一、把方法锁定,防止任何继承类修改它的意义和实现。

            第二、高效。编译器在遇到调用final方法时候会转入内嵌机制,大大提高执行效率。

        3、final变量(常量)

         用final修饰的成员变量表示常量,值一旦给定就无法改变!

         final修饰的变量有三种:静态变量、实例变量和局部变量,分别表示三种类型的常量。

         从下面的例子中可以看出,一旦给final变量初值后,值就不能再改变了。

     另外,final变量定义的时候,可以先声明,而不给初值,这中变量也称为final空白,无论什么情况,编译器都确保空白final在使用之前必须被初始化。但是,final空白在final关键字final的使用上提供了更大的灵活性,为此,一个类中的final数据成员就可以实现依对象而有所不同,却有保持其恒定不变的特征。

        4、final参数

        当函数参数为final类型时,你可以读取使用该参数,但是无法改变该参数的值。

        生成Java帮助文档:命令格式:javadoc –d 文件夹名 –auther –version *.java

            /** //格式

            *类描述

            *@author 作者名

            *@version 版本号

            */

            /**

            *方法描述

            *@param 参数描述

            *@return 返回值描述

            */

super

(1)使用super关键字, super代表父类对象super代表父类对象,只能用在子类中
(2)可在子类构造方法中调用且必须是该方法中第一句
(3)不能使用在static修饰的方法中
(4)super的用处

    访问父类构造方法
        super();
        super(name);
    访问父类属性
        super.name;
    访问父类方法
        super.print();

抽象类: abstract

抽象:不具体,看不明白。抽象类表象体现。

    在不断抽取过程中,将共性内容中的方法声明抽取,但是方法不一样,没有抽取,这时抽取到的方法,
    并不具体,需要被指定关键字abstract所标示,声明为抽象方法。

    抽象方法所在类一定要标示为抽象类,也就是说该类需要被abstract关键字所修饰。

抽象类的特点:

    1:抽象方法只能定义在抽象类中,抽象类和抽象方法必须由abstract关键字修饰(可以描述类和方法,不可以描述变量)。

    2:抽象方法只定义方法声明,并不定义方法实现。

    3:抽象类不可以被创建对象(实例化)。

    4:只有通过子类继承抽象类并覆盖了抽象类中的所有抽象方法后,该子类才可以实例化。否则,该子类还是一个抽象类。

抽象类的细节:

    1:抽象类中是否有构造函数?有,用于给子类对象进行初始化。

    2:抽象类中是否可以定义非抽象方法?

        可以。其实,抽象类和一般类没有太大的区别,都是在描述事物,只不过抽象类在描述事物时,有些功能不具体。
        所以抽象类和一般类在定义上,都是需要定义属性和行为的。
        只不过,比一般类多了一个抽象函数。而且比一般类少了一个创建对象的部分。

    3:抽象关键字abstract和哪些不可以共存?final , private , static

    4:抽象类中可不可以不定义抽象方法?可以。抽象方法目的仅仅为了不让该类创建对象。

面向对象的特征(封装)

封装是指隐藏对象的属性和实现细节,仅对外提供公共访问方式。

好处:将变化隔离;便于使用;提高重用性;安全性

封装原则:将不需要对外提供的内容都隐藏起来,把属性都隐藏,提供公共方法对其访问。

面向对象的特征(继承)

好处:

    1:提高了代码的复用性。

    2:让类与类之间产生了关系,提供了另一个特征多态的前提。

父类的由来:其实是由多个类不断向上抽取共性内容而来的。

java中对于继承,java只支持单继承。java虽然不直接支持多继承,但是保留了这种多继承机制,进行改良。

    单继承:一个类只能有一个父类。

    多继承:一个类可以有多个父类。

为什么不支持多继承呢?

    因为当一个类同时继承两个父类时,两个父类中有相同的功能,那么子类对象调用该功能时,运行哪一个呢?因为父类中的方法中存在方法体。

    但是java支持多重继承。A继承B B继承C C继承D。

    多重继承的出现,就有了继承体系。体系中的顶层父类是通过不断向上抽取而来的。它里面定义的该体系最基本最共性内容的功能。

    所以,一个体系要想被使用,直接查阅该系统中的父类的功能即可知道该体系的基本用法。、

    那么想要使用一个体系时,需要建立对象。建议建立最子类对象,因为最子类不仅可以使用父类中的功能。
    
    还可以使用子类特有的一些功能。

简单说:对于一个继承体系的使用,查阅顶层父类中的内容,创建最底层子类的对象。

子父类出现后,类中的成员都有了哪些特点:

    1:成员变量。

        当子父类中出现一样的属性时,子类类型的对象,调用该属性,值是子类的属性值。

        如果想要调用父类中的属性值,需要使用一个关键字:super

        This:代表是本类类型的对象引用。

        Super :代表是子类所属的父类中的内存空间引用。

        注意:子父类中通常是不会出现同名成员变量的,因为父类中只要定义了,子类就不用在定义了,直接继承过来用就可以了。

    2:成员函数。

        当子父类中出现了一模一样的方法时,建立子类对象会运行子类中的方法。

        好像父类中的方法被覆盖掉一样。所以这种情况,是函数的另一个特性:覆盖(复写,重写)

        什么时候使用覆盖呢?当一个类的功能内容需要修改时,可以通过覆盖来实现。

3:构造函数。

    发现子类构造函数运行时,先运行了父类的构造函数。为什么呢?

        原因:子类的所有构造函数中的第一行,其实都有一条隐身的语句super();

        super(): 表示父类的构造函数,并会调用于参数相对应的父类中的构造函数。而super():是在调用父类中空参数的构造函数。

    为什么子类对象初始化时,都需要调用父类中的函数?(为什么要在子类构造函数的第一行加入这个super()?)

        因为子类继承父类,会继承到父类中的数据,所以必须要看父类是如何对自己的数据进行初始化的。

        所以子类在进行对象初始化时,先调用父类的构造函数,这就是子类的实例化过程。

        注意:子类中所有的构造函数都会默认访问父类中的空参数的构造函数,因为每一个子类构造内第一行都有默认的语句super();

    如果父类中没有空参数的构造函数,那么子类的构造函数内,必须通过super语句指定要访问的父类中的构造函数。

    如果子类构造函数中用this来指定调用子类自己的构造函数,那么被调用的构造函数也一样会访问父类中的构造函数。 

    问题:super()和this()是否可以同时出现的构造函数中。

        两个语句只能有一个定义在第一行,所以只能出现其中一个。

        super()或者this():为什么一定要定义在第一行?

        因为super()或者this()都是调用构造函数,构造函数用于初始化,所以初始化的动作要先完成。

继承的细节:

什么时候使用继承呢?

    当类与类之间存在着所属关系时,才具备了继承的前提。a是b中的一种。a继承b。狼是犬科中的一种。

    英文书中,所属关系:” is a “

      注意:不要仅仅为了获取其他类中的已有成员进行继承。

    所以判断所属关系,可以简单看,如果继承后,被继承的类中的功能,都可以被该子类所具备,那么继承成立。如果不是,不可以继承。

细节二:

在方法覆盖时,注意两点:

    1:子类覆盖父类时,必须要保证,子类方法的权限必须大于等于父类方法权限可以实现继承。否则,编译失败。

    2:覆盖时,要么都静态,要么都不静态。 (静态只能覆盖静态,或者被静态覆盖)

        继承的一个弊端:打破了封装性。对于一些类,或者类中功能,是需要被继承,或者复写的。

这时如何解决问题呢?介绍一个关键字,final:最终。

    final特点:

        1:这个关键字是一个修饰符,可以修饰类,方法,变量。

        2:被final修饰的类是一个最终类,不可以被继承。

        3:被final修饰的方法是一个最终方法,不可以被覆盖。

        4:被final修饰的变量是一个常量,只能赋值一次。

    其实这样的原因的就是给一些固定的数据起个阅读性较强的名称。 

    不加final修饰不是也可以使用吗?那么这个值是一个变量,是可以更改的。

    加了final,程序更为严谨。常量名称定义时,有规范,所有字母都大写,如果由多个单词组成,中间用 _ 连接。

面向对象的特征(多态)

1. 多态的体现: ①方法的重载与重写     ②对象的多态性

2.对象的多态性:父类的引用指向子类的对象

    Person p = new Man(); // 多态-向上转型
    p.eat();
    p.walk(); //虚拟方法调用

    //p.smoking();

    Man man = (Man)p; //向下转型
    man.smoking();

    Java程序的运行分为两种状态:
    在多态的情况下,编译时, “看左边”,看的是父类的引用(父类中不具备子类特有的方法)
                  运行时,“看右边”,看的是子类对象,实际运行的是子类重写父类的方法

                ———— 以上过程被称为“虚拟方法调用(动态绑定)”

3. 多态的前提:①要有继承关系  ②方法的重写(完成虚拟方法调用)

4. 引用数据类型之间的转换:
    前提:要有继承关系
    向上转型: 子类转父类。系统自动完成转换
    向下转型: 父类转子类。需要使用强转符 “(需要转换的类型)”
    可能引发  java.lang.ClassCastException


Person p = new Man();
Woman woman = (Woman)p; //编译? YES       运行? NO

5. Java 为了解决上述问题,提供了相应的解决办法

instanceof 运算符:
    如:
        p instanceof Man :  判断 p 引用指向的对象是不是 Man 的本类类型及 Man 的子类类型,如果是返回 true

    Person p = new Man();
    if(p instanceof Woman){
        Woman woman = (Woman)p;   
    }       


多态的应用:

    多态的应用之一:多态数组

    Person[] persons = new Person[3];//该多态数组中可以存放Person本类类型的对象及Person子类类型的对象
    persons[0] = new Person();
    persons[1] = new Man();
    persons[2] = new Woman();

    for(int i = 0; i < persons.length; i++){
        persons[i].eat();//虚拟方法调用
    }


多态的应用之二: 多态参数

//需求:展示一个男人吃饭和走路的功能
/*public void show(Man man){
    man.eat();
    man.walk()
}

public void show(Woman woman){
    woman.eat();
    woman.walk();
}*/

public void show(Person p){ //多态参数:当调用方法时,可以传递Person本类类型的对象及Person子类类型的对象
    p.eat();
    p.walk();//虚拟方法调用

    if(p instanceof Man){
        Man man = (Man)p;
        man.smoking();
    }
}

equals和==的区别?

object中的equals比较的是地址,底层封装的是==

==比较的是基本数据类型,比较的是内容

引用数据类型比较的是地址

String中也有equals,String中的equals被重写过了,比较的是内容。

内部类

分类:成员内部类、静态内部类、局部内部类、匿名内部类

1、成员内部类:

    1、可以用四种访问权限修饰符修饰

    2、可以有自己的属性和方法,除了静态的。

    3、可以使用外部类的所有属性和方法,包括私有的。

    4、创建对象

        1、通过创建外部类对象的方式创建对象

        外部类 外部类对象=new 外部类();

        内部类 对象名=外部类对象.new 内部类();

        2、内部类 对象名=new 外部类.new 内部类();

2、静态内部类

    1、格式:static class 类名{}

    2、可以声明静态的属性和方法

    3、可以使用外部的静态的属性和方法

    4、创建对象

        内类名 对象名=new 内类名();(可以直接创建)

        外部类名.内部类 对象名=new  外部类.内部类();

        包名.外部类名.内部类 对象名=new  包名.外部类.内部类();

    5、外部类与内部类同名时,默认是使用内部类对象调用外部类属性

        this代表内部类对象

    6、要想使用外部类属性,需要使用外部类对象调用

3、局部内部类

    1、在方法中声明

    2、只能用default修饰

    3、可以声明属性和方法,但不能是静态的

    4、创建对象,必须在声明内部类的方法内创建

    5、调用方法的时候,局部内部类才会被执行

4、匿名内部类

    1、匿名内部类只是用一次

    2、格式:

    父类或接口名 对象名=new  父类或接口名(参数列表){

       重写抽象方法

            }

    调用抽象方法:对象名.方法名

数组及常用算法

一维数组

1、声明:

  int a[];  int []b;

2、初始化:

    动态初始化:1、a=new int[2]; int[0]=1;...

    动态初始化:2、b=new b[]{3,4};

    静态初始化:int [] c={5,6};

3、数组常用的方法:

    排序:Array.sort();

    查找:Array.binarySearch();

    打印:Array.toString();

    复制:Array.copyof();

4、常用操作

    1、冒泡排序

    for(int i=0;i<a.length-1;i++){//控制外循环的次数

        for(int j=0;j<a.length-1-i;j++){//控制内循环次数,比外循环少一次,与下一个比较

            if(a[j]>a[j+1]){

                int temp=a[j];

                a[j]=a[j+1];

                a[j+1]=temp;

            }

        }

    }

    2、选择排序

    for (int i = 0; i < a.length-1; i++) {

        int k=i;

        for (int j = i; j < a.length-1; j++) {

            if (a[k]>a[j+1]) {

                k=j+1;

            }

        }

        if(i!=k){

            int temp=a[i];

            a[i]=a[k];

            a[k]=temp;

        }

    }

    3、顺序查找

    public static int find(int []b,int a){

    for (int i = 0; i < b.length; i++) {

        if (a==b[i]) {

            return i;

        }

    }

    return -1;

    }

    4、二分查找

    public static int find(int b[],int a){

    int max=b.length-1;

    int min=0;

    for (int i = 0; i < b.length; i++) {

        int midle=(max+min)/2;

        if(a==b[midle]){

            return midle;

        }else if(a>b[midle]){

           min=midle+1;

        }else if(a<b[midle]){

            max=midle-1;

        }

    }

    

return -1;

}

结尾

java总结上部分差不多就结束了,由于有些知识超纲后续发现不足会进行修改,望各位大牛多多指点

© 版权声明
THE END
喜欢就支持一下吧
点赞2赞赏 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容