【黑马程序员】Java基础知识1

 -------android培训、java培训、期待与您交流! ----------

1. Java数据类型

        Java是强类型语言,所有的变量必须先声明后使用,定义变量需要显示的声明一个在编译时就能确定的类型。
        Java中的数据类型有两种,基本类型(Primitive Type)和引用类型(Reference Type)。
        1)基本数据类型

        Java基本类型分为两类:数值型和布尔型。数值型可分为整型以及浮点型,整形中的字符型也可单独分为一类。所以一般把基本类型分为4类,如下表:

分类 类型 长度
整数型 int 32位
long 64位
short 16位
byte 8位
字符型 char 16位
浮点型 double 64位
float 32位
布尔型 boolean 1位


        ①整型:int为最常用的整型变量。系统中的整数常量会被看作int处理。但有以下两个例外:
  • 如果一个整数很小(在byte或short)的范围内,当这个整数常量被付给一个byte或short变量时,整数常量会被当作byte或short类型。
  • 如果一个巨大的整数常量(超出了Int的存储范围)时,系统不会把这个整数当作long类型处理,除非用户在常量后加上一个字母"L"。
        示例:
public class IntegerValTest {
    public static void main(String[] args) {
        //下面代码是正确的,系统会自动把56当成byte类型处理
        byte a = 56;
        /*
        下面代码是错的,系统不会把9999999999999当成long类型处理,
        所以超出int的表数范围,从而引起错误
        */
        //long bigValue = 9999999999999;
        //下面代码是正确的,在巨大的整数常量后使用L后缀,强制使用long类型
        long bigValue2 = 9223372036854775807L;
    
        //以0开头的整数常量是8进制的整数
        int octalValue = 013;
        System.out.println(octalValue);
        //以0x或0X开头的整数常量是16进制的整数
        int hexValue1 = 0x13;
        int hexValue2 = 0XaF;


        System.out.println(hexValue1);
        System.out.println(hexValue2);


        // 定义二个8位的二进制数
        int binVal1 = 0b11010100;
        byte binVal2 = 0b01101001;
        // 定义一个32位的二进制数,最高位是符号位。
        int binVal3 = 0B10000000000000000000000000000011;
        System.out.println(binVal1); // 输出212
        System.out.println(binVal2); // 输出105
        System.out.println(binVal3); // 输出-2147483645
        /*
         定义一个8位的二进制,该数值默认占32位,因此它是一个正数。
         只是强制类型转换成byte时产生了溢出,最终导致binVal4变成了-23
         */
        byte binVal4 =  (byte)0b11101001;
        /*
          定义一个32位的二进制数,最好位是符号位。
          但由于数值后添加了L后缀,因此该整数的实际占64位,第32位的1不是符号位。
          因此binVal5的值等于2的31次方 + 2 + 1
         */
        long binVal5 = 0B10000000000000000000000000000011L;
        System.out.println(binVal4); // 输出-23
        System.out.println(binVal5); // 输出2147483651
    }
}

        ②字符型
        字符型用于表示耽搁的字符。字符常量通常用单引号(')括起来。Java使用unicode编码方式,所以字符型变量能够表示大部分国家的文字字符。
        字符表示有以下几种方式:
  • 直接使用字符常量:如 ‘a’、'我'等。
  • 使用转移字符:如'\n'、'\t'等。
  • 使用unicode表示字符:如'\uxxxx',其中x表示一个十六进制整数。

        如果把一个整数(0~65535之间)常量赋给字符类型变量,系统会把整数当作char处理。       

        示例:

public class CharTest {
    public static void main(String[] args) {
        //直接指定单个字符作为字符常量
        char aChar = 'a';
        //使用转义字符来作为字符常量
        char enterChar = '\r';
        //使用Unicode编码值来指定字符常量
        char ch = '\u9999';
        //将输出一个'香'字符
        System.out.println(ch);
        // 定义一个'疯'字符常量
        char zhong = '疯';
        // 直接将一个char变量当成int类型变量使用
        int zhongValue = zhong;
        System.out.println(zhongValue);
        //直接把一个0~65535范围内的int整数赋给一个char变量
        char c = 97;
        System.out.println(c);
    }
}

        ③浮点型
        Java中浮点型有两种:double和float,两个浮点型的长度分别为64位和32位,且长度不因环境的改变而改变。浮点数的特点是不能够精确的表示一个小数位数较多的小数。
        浮点数有两种表示方式:
  • 十进制表示:3.11、5.2、4等
  • 科学计数法表示:4.12E3、5.12E2;
        java中一个浮点数常量默认为double类型,如果要系统把一个小数常量当作float处理,需要在小数后加上f字母。
        示例:
public class FloatTest {
    public static void main(String[] args) {
        float af = 5.2345556f;
        //下面将看到af的值已经发生了改变
        System.out.println(af);
        double a = 0.0;
        double c = Double.NEGATIVE_INFINITY;
        float d = Float.NEGATIVE_INFINITY;
        //看到float和double的负无穷大是相等的。
        System.out.println(c == d);
        //0.0除以0.0将出现非数
        System.out.println(a / a);
        //两个非数之间是不相等的
        System.out.println(a / a == Float.NaN);
        //所有正无穷大都是相等的
        System.out.println(6.0 / 0 == 555.0/0);
        //负数除以0.0得到负无穷大
        System.out.println(-8 / a);
        //下面代码将抛出除以0的异常
        //System.out.println(0 / 0);
    }
}       

        ④布尔型
        布尔型只有一个boolean类型,用于表示逻辑真或者逻辑假。boolean的值只能为true或者是false,其他基本类型不能转换到boolean类型。
        示例:
public class BooleanTest {
    public static void main(String[] args) {
        boolean b1 = true;
        boolean b2 = false;
        //下面代码将出现错误:字符串不能直接变成boolean型的值
        //boolean b3 = "true";
        //使用boolean和字符串进行连接运算,boolean会自动转换成字符串
        String str = true + "";
        //下面将输出true
        System.out.println(str);
    }
}    

        2)基本类型之间的转换
        Java中基本类型有两种转换方式自动转换和强制转换。讲一个表数范围小的变量赋给一个表数范围大的变量,系统将进行自动转换,将小便量转换为大变量在进行赋值操作。
        示例:
public class AutoPromote {
    public static void main(String[] args) {
        //定义一个short类型变量
        short sValue = 5;
        //下面代码将出错:表达式中的sValue将自动提升到int类型,
        //则右边的表达式类型为int,将一个int类型赋给short类型的变量将发生错误。
        //sValue = sValue - 2;
        byte b = 40;
        char c = 'a';
        int i = 23;
        double d = .314;
        //右边表达式中在最高等级操作数为d(double型)
        //则右边表达式的类型为double型,故赋给一个double型变量
        double result = b + c + i * d;
        //将输出144.222
        System.out.println(result);
        int val = 3;
        //右边表达式中2个操作数都是int,故右边表达式的类型为int
        //因此,虽然23/3不能除尽,依然得到一个int整数
        int intResult = 23 / val;
        //将输出7
        System.out.println(intResult);
        //输出字符串Hello!a7
        System.out.println("Hello!" + 'a' + 7);
        //输出字符串104Hello!
        System.out.println('a' + 7 + "Hello!");


    }
}  

        如果系统把大范围变量转换为小范围变量就需要强制转换,强制转换的语法格式是(type)value,可将valae强制转换为type类型的变量。当强制转换可能会导致数据精度的丢失,请看示例:
public class NarrowConversion {
    public static void main(String[] args) {
        int iValue = 233;
        //强制把一个int类型的值转换为byte类型的值
        byte bValue = (byte)iValue;
        //将输出-23
        System.out.println(bValue);
        double dValue = 3.98;
        //强制把一个double类型的值转换为int
        int tol = (int)dValue;
        // 将输出3
        System.out.println(tol);
    }
}       

        3)表达式类型的自动提升
        当一个算术表达式中包含多个基本类型时,整个表达式的类型会发生自动提升,Java定义了如下的提升规则:
  • 所有的byte类型,short类型和char经提升到int类型。
  • 怎个算术表达式的数据类型提升到最高等级操作时的类型。
        示例:
public class AutoPromote {
    public static void main(String[] args) {
        //定义一个short类型变量
        short sValue = 5;
        //下面代码将出错:表达式中的sValue将自动提升到int类型,
        //则右边的表达式类型为int,将一个int类型赋给short类型的变量将发生错误。
        //sValue = sValue - 2;
        byte b = 40;
        char c = 'a';
        int i = 23;
        double d = .314;
        //右边表达式中在最高等级操作数为d(double型)
        //则右边表达式的类型为double型,故赋给一个double型变量
        double result = b + c + i * d;
        //将输出144.222
        System.out.println(result);
        int val = 3;
        //右边表达式中2个操作数都是int,故右边表达式的类型为int
        //因此,虽然23/3不能除尽,依然得到一个int整数
        int intResult = 23 / val;
        //将输出7
        System.out.println(intResult);
        //输出字符串Hello!a7
        System.out.println("Hello!" + 'a' + 7);
        //输出字符串104Hello!
        System.out.println('a' + 7 + "Hello!");
    }
}

2. Java数组的使用

        数组是编程语言中最常见的一种数据结构,可以存储多了元素,通常可以通过数组元素的索引来访问数组元素,包括为数组元素赋值和取出数组元素的值。


        1)数组也是一种类型
  • Java中数组要求所包含的元素必须是同一数据类型。在一个数组中,元素的类型时唯一的。一单数组被初始化后,它在内存中占用的空间就确定了,不管数组中是否存放了元素。
  • Java的数组也是一种数据类型,是一种引用类型,例如int是一个基本类型,但int[]就是一个引用类型了。
        2)定义数组‘
        可以使用两种方式定义数组
  • type[] arrayName;
  • type arrayName[];
        推荐使用第一种,更加突出数组是一种数据类型。

        3)数组的初始化
        Java中的变量都必须先初始化才可以使用。所谓初始化,就是为数组的元素分配内存空间并为每个元素赋初值。
        注意:只要为数组元素分配了内存空间,那么元素就一定有一个初始值。
        数组的初始化有如下两种方式:
  • 静态初始化:初始化时用户显示的指定每个数组元素的初始值,由系统决定数组长度。
  • 动态初始化:初始化中用户指定数组长度,由系统为元素分配初始值。

        静态初始化的语法如下:

        arrayName = new type[]{element1, element2, element3...}
        type是数组中元素的类型,等号后面的type类型只能是前面和前面type的类型相同或是其子类。
        示例:
//定义一个int数组类型的变量,变量名为intArr.
int[] intArr;
//使用静态初始化,初始化数组时只指定数组元素的初始值,不指定数组长度。
intArr = new int[]{5, 6, 8, 20};
//定义一个Object数组类型的变量,变量名为objArr.
Object[] objArr;
//使用静态初始化,初始化数组时数组元素的类型是
//定义数组时数组元素类型的子类
objArr = new String[]{"Java" , "张三"};
Object[] objArr2;
//使用静态初始化
objArr2 = new Object[] {"Java" , "张三"};
        除此之外,静态初始化还有如图下的语法格式:
        arrayName = {element1, element2, element3...}
        在这种语法格式中,直接使用花括号定义第一数组:例如
//数组的定义和初始化同时完成,使用简化的静态初始化写法
int[] a = {5, 6 , 7, 9};   

        动态初始化:
        动态初始化只指定数组的长度,由系统默认为数组元素赋初值,格式如下:
        arrayName = new type[length];
        示例:
//数组的定义和初始化同时完成,使用动态初始化语法
int[] prices = new int[5];
//数组的定义和初始化同时完成,初始化数组时元素的类型是定义数组时元素类型的子类
Object[] books = new String[4];

        系统在分配元素的初值时,按一下规则:
  • 如元素为基本类型中的整型,默认值为 0;
  • 如是基本类型中的浮点型,默认值为 0.0;
  • 如实基本类型中的字符型,默认值为 '\u0000';
  • 如实基本类型中的布尔型,默认值为 false;
  • 如是引用类型,默认值为 null;

        4)使用数组
        创建一个数组后,可通过数组下表访问(从0开始),可使用for循环来遍历数组元素,也可使用更简洁的foreach进行遍历。
        示例:
public class ForEachErrorTest {
    public static void main(String[] args)  {
        String[] books = {"高等数学" , 
        "大学英语",
        "大学物理"};
        //使用foreach循环来遍历数组元素,其中book将会自动迭代每个数组元素
        for (String book : books)
        {
            book = "高等数学";
            System.out.println(book);
        }
        System.out.println(books[0]);
    }
}
        注意:使用foreach遍历数组时,不能改变数组元素的值,所以不要对foreach的循环变量进行赋值。


        5)深入数组
        数组变量是引用类型,它指向内存中数组区域的第一个元素。数组元素和数组变量在内存中是分开存放的。实际的数组对象存储在堆内存中,如果引用该数组的引用变量是一个局部变量,那么它被存放在栈内存中。如下图所示:

【黑马程序员】Java基础知识1_第1张图片
        如果堆内存中不在有任何的引用变量指向自己,则这个数组将成为垃圾,等待垃圾回收机制回收。因此,为了将一个数组回收,可将数组引用变量赋值为null。,切断其与数组之间的联系。
        只要类型相互兼容,就可以让一个数组指向另一个实际的数组,如下所示:
public class ArrayInRam {
    public static void main(String[] args) {
        //定义并初始化数组,使用静态初始化
        int[] a = {5, 7 , 20};
        //定义并初始化数组,使用动态初始化
        int[] b = new int[4];
        //输出b数组的长度
        System.out.println("b数组的长度为:" + b.length);
        //循环输出a数组的元素
        for (int i = 0 ,len = a.length; i < len ; i++ ) {
            System.out.println(a[i]);
        }
        //循环输出b数组的元素
        for (int i = 0 , len = b.length; i < len ; i++ ) {
            System.out.println(b[i]);
        }
        //因为a是int[]类型,b也是int[]类型,所以可以将a的值赋给b。
        //也就是让b引用指向a引用指向的数组
        b = a;
        //再次输出b数组的长度
        System.out.println("b数组的长度为:" + b.length);
    }
}

3、封装

       1)private私有;

       2)public  公有;(set设置、get查看)

       3)static修饰符

       static可以修饰成员变量和成员函数

        ①static成员变量:

  • 被所有对象共享,只有一份副本
  • 通过“对象名”或“类名”都可以访问
  • static的成员变量是在当我们第一次使用该类时,首先被存储在静态区内。在没有此类对象的情况下,就已经存在了。
  • 静态成员变量只有一份拷贝,任何对象修改后,其他对象看到的都是新值

        2)static 成员函数

  • 可以将一个方法声明为static
  • 静态方法在没有类对象的情况下就产生了
  • 可以通过类名调用,也可以通过对象名调用
  • 静态的方法不能访问非静态的成员变量。因为静态方法在没有对象存在的情况下就已经先期存在,但是此时没有任何对象存在,也就没有对象的成员变量空间和值,所以,无法访问

          static成员函数应用:

  • 经常在一个类中定义若干多的静态方法,例如:求三个数的最大值,还有对数组排序等等
  • 供整个项目共享,通过类名可以直接使用

        3)static(静态)初始化代码块

  • 使用static定义代码块,当第一次使用该类、或访问该类成员时,执行一次,     且只执行一次
  • 静态初始化代码块只能访问静态成员变量、调用静态成员方法

4. 继承extends

       1.当我们面向对象设计时,会发现一些已抽取的类中,有一些相同的属性或方法。这时我们可以对这些具有重复属性或方法的类进行进一步抽取。

       2.将抽取后的类,作为基类,可以被其他类“继承”,达到一个“重用” 的目的

       3.一个类“继承”其他类,使用关键字extends

        继承的特点:

  • Java只支持单继承,不支持多继承
  • Java允许多级继承
  • 不要仅为了获取其他类中某个功能而去继承

       类与类之间的关系:(UML)

       1.继承关系(is a)(一般关系):子类继承父类

       2.关联关系(has a有一个,多个):例如:学员类和科目类(学员要有一个科目)

       3.组合关系:一个类,有多个其他类组成的。

       4.依赖关系:一般在类中不持有另外一个类的引用,但是某些方法需要另外类型的引用 这时、这个类依赖于参数类

        Super关键字/函数的重写

       1.子类定义了跟父类同名的成员变量,这时、这个变量将覆盖(隐藏)了父的同名变量

       2.在子类中,可以使用super关键字显示的调用父类被隐藏的成员变量

       访问修饰符:private(私有的)-> 默认 ->protected(受保护的)->public(公共的)

       函数的重写(Override)(覆盖、重写)

      

       1.子类中可以出现跟父类一样的方法,这时就是:函数的重写

         1).返回值类型 方法名参数列表:完全相同

         2).访问修饰符:子类重写父类的方法时,访问修饰符必须同重写的方法一致,或更宽的访问修饰符(不包括private)

            2.1).编译时,检查如果方法名、参数列表相同,返回值不同将出现编译错误

               2.2).如果返回值类型、方法名相同,参数列表不同,可以编译运行, 这个是子类特有的方法,和父类show()方法没有关系

 

       2.private方法不能被重写:

         1).子类可以定义一个和父类相同的private的方法,但这不是“重写”, 各自独立的。(即两边都是私有的)


5. 多态

       多态的特点

       1.成员变量:父类访问的变量始终是父类自己的(对于父类自己的变量及被覆   盖的变量)

       2.成员方法:编译的时候看父类中是否有方法,如果没有,编译错误,运行的时候是子类的方法

       3.静态方法:被覆盖的静态成员,访问的是父类的。一般情况下,多态性访问的都是父类的,父类有,则编译通过,否则编译失 败 有一个特殊,对于被覆盖的成员方法,运行时是子类的,父类引用,不能访问子类特有的成员



你可能感兴趣的:(黑马)