Java笔记

变量类型

  1. 类变量 独立于方法之外的变量 用static修饰

  2. 实例变量 独立于方法之外的变量 没有static修饰

  3. 局部变量 类的方法中的变量

  4. 类变量可在类中直接使用,实例变量需实例化后才能使用。 简而言之就是static修饰了之后就与对象无关了 可以不实例化对象直接使用了 非static方法以及变量需要实例化对象才能够使用

    public class StaticTest {
        private static int staticInt = 2;
        private int random = 2;
    
        public static void main(String[] args) {
            System.out.println(staticInt);
            StaticTest test = new StaticTest();
            System.out.println(test.random);
        }
    }
    

    修饰符

    1. private 在同一类内可见 使用对象: 变量 方法 不能够修饰类(外部类)private 的方法、变量和构造方法只能被所属类访问 并且类和接口不能声明为 private

    2. public 对所有类可见 类 接口 变量 方法都可以使用 被声明为 public 的类、方法、构造方法和接口能够被任何其他类访问。

      如果几个相互访问的 public 类分布在不同的包中,则需要导入相应 public 类所在的包。由于类的继承性,类所有的公有方法和变量都能被其子类继承。

    3. protected 对同一包内的类和所有子类可见 使用对象 变量 方法 不能够修饰类(外部类)

      • 子类与基类在同一包中:被声明为 protected 的变量、方法和构造器能被同一个包中的任何其他类访问;
      • 子类与基类不在同一包中:那么在子类中,子类实例可以访问其从基类继承而来的 protected 方法,而不能访问基类实例的protected方法。

      接口及接口的成员变量和成员方法不能声明为 protected。

      子类能访问 protected 修饰符声明的方法和变量,这样就能保护不相关的类使用这些方法和变量。

    4. default 在同一包内可见 不适用任何修饰符 适用对象 类 接口 变量 方法

      image-20210624144918812

    访问控制和继承

    1. 父类中声明为public的方法在子类也必须为public
    2. 父类中声明为protected的方法在子类中要么声明为protected 要么声明为public 不能声明为private
    3. 父类中声明为private的方法 不能够被继承

    非访问修饰符

    static 修饰符,用来修饰类方法和类变量。

    static 关键字用来声明独立于对象的静态变量,无论一个类实例化多少对象,它的静态变量只有一份拷贝。 静态变量也被称为类变量。局部变量不能被声明为 static 变量。

    static 关键字用来声明独立于对象的静态方法。静态方法不能使用类的非静态变量。静态方法从参数列表得到数据,然后计算这些数据。

    final 修饰符,用来修饰类、方法和变量,final 修饰的类不能够被继承修饰的方法不能被继承类重新定义,修饰的变量为常量,是不可修改的。final 表示"最后的、最终的"含义,变量一旦赋值后,不能被重新赋值。被 final 修饰的实例变量必须显式指定初始值。

    final 修饰符通常和 static 修饰符一起使用来创建类常量。

    父类中的 final 方法可以被子类继承,但是不能被子类重写。

    声明 final 方法的主要目的是防止该方法的内容被修改。

    final 类不能被继承,没有类能够继承 final 类的任何特性。

    abstract 修饰符,用来创建抽象类和抽象方法

    抽象类不能用来实例化对象,声明抽象类的唯一目的是为了将来对该类进行扩充。

    一个类不能同时被 abstract 和 final 修饰。如果一个类包含抽象方法,那么该类一定要声明为抽象类,否则将出现编译错误。

    抽象类可以包含抽象方法和非抽象方法。

    抽象方法是一种没有任何实现的方法,该方法的的具体实现由子类提供。

    任何继承抽象类的子类必须实现父类的所有抽象方法,除非该子类也是抽象类。

    如果一个类包含若干个抽象方法,那么该类必须声明为抽象类。抽象类可以不包含抽象方法。抽象方法的声明以分号结尾

    public abstract class SuperClass{
     abstract void m(); //抽象方法
    }
    
    class SubClass extends SuperClass{
      //实现抽象方法
       void m(){
           .........
       }
    }
    

    synchronized 和 volatile 修饰符,主要用于线程的编程。

    synchronized 关键字声明的方法同一时间只能被一个线程访问。synchronized 修饰符可以应用于四个访问修饰符。

运算符

条件运算符

  1. variable x = (expression) ? value if true : value if false
    public class Test {
       public static void main(String[] args){
          int a , b;
          a = 10;
          // 如果 a 等于 1 成立,则设置 b 为 20,否则为 30
          b = (a == 1) ? 20 : 30;
          System.out.println( "Value of b is : " +  b );
     
          // 如果 a 等于 10 成立,则设置 b 为 20,否则为 30
          b = (a == 10) ? 20 : 30;
          System.out.println( "Value of b is : " + b );
       }
    }
    

instanceof 运算符

( Object reference variable ) instanceof  (class/interface type)

如果运算符左侧变量所指的对象,是操作符右侧类或接口(class/interface)的一个对象,那么结果为真。

循环结构

for循环
for(初始化; 布尔表达式; 更新) {
    //代码语句
}

java 增强for循环

主要用于数组的增强型for循环

for(声明语句 : 表达式)
{
   //代码句子
}

声明语句:声明新的局部变量,该变量的类型必须和数组元素的类型匹配。其作用域限定在循环语句块,其值与此时数组元素的值相等。

表达式:表达式是要访问的数组名,或者是返回值为数组的方法。

switch case 语句

  • 当变量的值与 case 语句的值相等时,那么 case 语句之后的语句开始执行,直到 break 语句出现才会跳出 switch 语句。

switch case 执行时,一定会先进行匹配,匹配成功返回当前 case 的值,再根据是否有 break,判断是否继续输出,或是跳出判断。

Number & Math类

所有的包装类(Integer、Long、Byte、Double、Float、Short)都是抽象类 Number 的子类。

Number 类属于 java.lang 包。

Java 的 Math 包含了用于执行基本数学运算的属性和方法,如初等指数、对数、平方根和三角函数。

Math 的方法都被定义为 static 形式,通过 Math 类可以在主函数中直接调用。

Number & Math 类方法

  1. xxxValue()方法

    将 Number 对象转换为xxx数据类型的值并返回。 直接调用就行 对象.需要转换的类型value()

  2. compareTo()

    将number对象与参数比较

    该方法用于两个相同数据类型的比较,两个不同类型的数据不能用此方法来比较。

    调用方式 x.compareTo(3)

    对比结果情况:

    • 如果指定的数与参数相等返回0。
    • 如果指定的数小于参数返回 -1。
    • 如果指定的数大于参数返回 1。
  3. equals()方法

    用于判断 Number 对象与方法的参数进是否相等。

    如 Number 对象不为 Null,且与方法的参数类型与数值都相等返回 True,否则返回 False。

  4. valueOf()

    用于返回给定参数的原生 Number 对象值,参数可以是原生数据类型, String等。

    该方法是静态方法。该方法可以接收两个参数一个是字符串,一个是基数。

    static Integer valueOf(int i)
    static Integer valueOf(String s)
    static Integer valueOf(String s, int radix)
    
    • i -- Integer 对象的整数。

    • s -- Integer 对象的字符串。

    • radix --在解析字符串 s 时使用的进制数,用于指定使用的进制数。

      实例

      **public** **class** Test{
      **public** **static** **void** main(String args[]){
              Integer x =Integer.valueOf(9);
              Double c = Double.valueOf(5);
              Float a = Float.valueOf("80");        
      
      ​        Integer b = Integer.valueOf("444",16);  *// 使用 16 进制*
      
      ​        System.out.println(x);
      ​        System.out.println(c);
      ​        System.out.println(a);
      ​        System.out.println(b);
      ​    }
      }
      
      9
      5.0
      80.0
      1092
      
  5. toString()

    用于返回以一个字符串表示的 Number 对象值。 就是把数字转换成字符串 字面意思

    如果方法使用了原生的数据类型作为参数,返回原生数据类型的 String 对象值。

    如果方法有两个参数, 返回用第二个参数指定基数表示的第一个参数的字符串表示形式。

    语法

    String toString()
    static String toString(int i)
    
    • i -- 要转换的整数。

    • toString(): 返回表示 Integer 值的 String 对象。

    • toString(int i): 返回表示指定 int 的 String 对象。

    • 实例

    • public class Test{
          public static void main(String args[]){
              Integer x = 5;
      
              System.out.println(x.toString());  
              System.out.println(Integer.toString(12)); 
          }
      }
      
      5
      12
      
  6. parseInt()

    用于将字符串参数作为有符号的十进制整数进行解析。 简而言之 就是把字符串的数字转换成数字类型输出 跟toString()相反

    如果方法有两个参数, 使用第二个参数指定的基数,将字符串参数解析为有符号的整数。

    static int parseInt(String s)
    
    static int parseInt(String s, int radix)
    
    • s -- 十进制表示的字符串。

    • radix -- 指定的基数。

    • parseInt(String s): 返回用十进制参数表示的整数值。

    • parseInt(int i): 使用指定基数的字符串参数表示的整数 (基数可以是 10, 2, 8, 或 16 等进制数) 。

    • 话不多说 直接看实例

    • public class Test{
          public static void main(String args[]){
              int x =Integer.parseInt("9");
              double c = Double.parseDouble("5");
              int b = Integer.parseInt("444",16);
      
              System.out.println(x);
              System.out.println(c);
              System.out.println(b);
          }
      }
      
      9
      5.0
      1092
      
  7. abs()

    返回参数的绝对值。参数可以是 int, float, long, double, short, byte类型。

    double abs(double d)
    float abs(float f)
    int abs(int i)
    long abs(long lng)
    

    实例

    public class Test{ 
     public static void main(String args[]){
         Integer a = -8;
         double d = -100;
         float f = -90;    
    
         System.out.println(Math.abs(a));
         System.out.println(Math.abs(d));     
         System.out.println(Math.abs(f));    
     }
    }
    
    8
    100.0
    90.0
    
  8. ceil()

    可对一个数进行上舍入,返回值大于或等于给定的参数,类型为双精度浮点型。

    简而言之 往大了的约等与

    double ceil(double d)
    
    double ceil(float f)
    
    • double 或 float 的原生数据类型。

    • public class Test{
          public static void main(String args[]){
              double d = 100.675;
              float f = -90;    
      
              System.out.println(Math.ceil(d));
              System.out.println(Math.ceil(f)); 
      
              System.out.println(Math.floor(d));
              System.out.println(Math.floor(f)); 
          }
      }
      
    • 101.0
      -90.0
      100.0
      -90.0
      
  9. floor()

    方法可对一个数进行下舍入,返回给定参数最大的整数,该整数小于或等给定的参数。

    往小了的约等于

    double floor(double d)
    
    double floor(float f)
    
    public class Test{
     public static void main(String args[]){
         double d = 100.675;
         float f = -90;
    
         System.out.println(Math.floor(d));
         System.out.println(Math.floor(f));
    
         System.out.println(Math.ceil(d));
         System.out.println(Math.ceil(f));
     }
    }
    
    100.0
    -90.0
    101.0
    -90.0
    
  10. rint()

    返回最接近参数的整数值。 真正的四舍五入

    double 类型数据。

  11. round()

    返回一个最接近的 int、long 型值,四舍五入。

    round 表示"四舍五入",算法为Math.floor(x+0.5) ,即将原来的数字加上 0.5 后再向下取整,所以 Math.round(11.5) 的结果为 12,Math.round(-11.5) 的结果为 -11。

    long round(double d)
    
    int round(float f)
    
  12. min()

    方法用于返回两个参数中的最小值。

    public class Test{
     public static void main(String args[]){
         System.out.println(Math.min(12.123, 12.456));      
         System.out.println(Math.min(23.12, 23.0));  
     }
    }
    
    12.123
    23.0
    
  13. max()

    用于返回两个参数中的最大值。

    使用方法类似于min的使用方法

  14. exp()

    用于返回自然数底数e的参数次方。

    double exp(double d)
    
    public class Test{ 
     public static void main(String args[]){
         double x = 11.635;
         double y = 2.76;
    
         System.out.printf("e 的值为 %.4f%n", Math.E);
         System.out.printf("exp(%.3f) 为 %.3f%n", x, Math.exp(x));  
     }
    }
    
    e 的值为 2.7183
    exp(11.635) 为 112983.831
    
  15. log()

    用于返回参数的自然数底数的对数值。

    public class Test{
     public static void main(String args[]){
         double x = 11.635;
         double y = 2.76;
    
         System.out.printf("e 的值为 %.4f%n", Math.E);
         System.out.printf("log(%.3f) 为 %.3f%n", x, Math.log(x));
     }
    }
    
    e 的值为 2.7183
    log(11.635) 为 2.454
    
  16. pow()

    用于返回第一个参数的第二个参数次方。

    double pow(double base, double exponent)
    
    • base -- 任何原生数据类型。
    • exponent -- 任何原生数据类型。
  17. sqrt()

    用于返回参数的算术平方根。

    double sqrt(double d)
    
    public class Test{ 
     public static void main(String args[]){
         double x = 11.635;
         double y = 2.76;
    
         System.out.printf("e 的值为 %.4f%n", Math.E);
         System.out.printf("sqrt(%.3f) 为 %.3f%n", x, Math.sqrt(x));
     }
    }
    
    e 的值为 2.7183
    sqrt(11.635) 为 3.411
    
  18. random()

    用于返回一个随机数,随机数范围为 0.0 =< Math.random < 1.0。

    public class Test{
     public static void main(String args[]){
         System.out.println( Math.random() );
         System.out.println( Math.random() );
     }
    }
    
    0.5444085967267008
    0.7960235983184115
    

    int 和 Integer 所占内存比较:

    Integer 对象会占用更多的内存。Integer 是一个对象,需要存储对象的元数据。但是 int 是一个原始类型的数据,所以占用的空间更少。

Character 类

Character 类用于对单个字符进行操作。

Character 类在对象中包装一个基本类型 char 的值

char ch = 'a';
 
// Unicode 字符表示形式
char uniChar = '\u039A'; 
 
// 字符数组
char[] charArray ={ 'a', 'b', 'c', 'd', 'e' };
Character ch = new Character('a');

方法

  1. isLetter() 就是一个判断是不是字母的方法

    用于判断指定字符是否为字母。

    boolean isLetter(char ch)
    
    • ch -- 要测试的字符。

      如果字符为字母,则返回 true;否则返回 false。

      public class Test {
      
       public static void main(String args[]) {
           System.out.println(Character.isLetter('c'));
           System.out.println(Character.isLetter('5'));
       }
      }
      
      true
      false
      
  2. isDigit() 就是一个判断是不是数字的方法

    用于判断指定字符是否为数字。

    public static boolean isDigit(char ch)
    
    • ch -- 要测试的字符。
    • 如果字符为数字,则返回 true;否则返回 false。
  3. isWhitespace()

    就是一个判断是不是 空白字符的方法

    用于判断指定字符是否为空白字符,空白符包含:空格、tab 键、换行符。

    boolean isWhitespace(char ch)
    
    • ch -- 要测试的字符。
    • 如果字符为空白字符,则返回 true;否则返回 false。
  4. image-20210624170744778

  5. image-20210624170814753

  6. toUpperCase()

    用于将小写字符转换为大写。

    char toUpperCase(char ch)
    
    • ch -- 要转换的字符。
    • 返回转换后字符的大写形式,如果有的话;否则返回字符本身。
  7. image-20210624171121693

  8. toString()

    用于返回一个表示指定 char 值的 String 对象。结果是长度为 1 的字符串,仅由指定的 char 组成。

String类

创建字符串

String str = "Runoob";

String str2=new String("Runoob");

其中一种初始化字符串的方法

public class StringDemo{public static void main(String args[]){   char[] helloArray = { 'r', 'u', 'n', 'o', 'o', 'b'};   String helloString = new String(helloArray);     System.out.println( helloString );}}

String 类是不可改变的,所以你一旦创建了 String 对象,那它的值就无法改变了

如果需要对字符串做很多修改,那么应该选择使用 StringBuffer & StringBuilder 类

字符串长度

用于获取有关对象的信息的方法称为访问器方法。

public class StringDemo { public static void main(String args[]) {     String site = "www.runoob.com";     int len = site.length();     System.out.println( "菜鸟教程网址长度 : " + len );}}

链接字符串

String 类提供了连接两个字符串的方法:

string1.concat(string2);

返回 string2 连接 string1 的新字符串。也可以对字符串常量使用 concat() 方法,如:

"我的名字是 ".concat("Runoob");

更常用的是使用'+'操作符来连接字符串,如:

"Hello," + " runoob" + "!"

创建格式化字符串

我们知道输出格式化数字可以使用 printf() 和 format() 方法。

String 类使用静态方法 format() 返回一个String 对象而不是 PrintStream 对象。

String 类的静态方法 format() 能用来创建可复用的格式化字符串,而不仅仅是用于一次打印输出。

System.out.printf("浮点型变量的值为 " +               "%f, 整型变量的值为 " +               " %d, 字符串变量的值为 " +               "is %s", floatVar, intVar, stringVar);
String fs;fs = String.format("浮点型变量的值为 " +                "%f, 整型变量的值为 " +                " %d, 字符串变量的值为 " +                " %s", floatVar, intVar, stringVar);

String 的方法

  1. charAt()

    用于返回指定索引处的字符。索引范围为从 0 到 length() - 1。

    public class Test { public static void main(String args[]) {     String s = "www.runoob.com";     char result = s.charAt(6);     System.out.println(result); }}
    
    n
    
  2. compareTo()

    • 字符串与对象进行比较。

    • 按字典顺序比较两个字符串。

    • int compareTo(Object o) 或 int compareTo(String anotherString)

    • 如果第一个字符和参数的第一个字符不等,结束比较,返回第一个字符的ASCII码差值。

      如果第一个字符和参数的第一个字符相等,则以第二个字符和参数的第二个字符做比较,以此类推,直至不等为止,返回该字符的ASCII码差值。 如果两个字符串不一样长,可对应字符又完全一样,则返回两个字符串的长度差值。

    public class Test {    public static void main(String args[]) {        String str1 = "Strings";        String str2 = "Strings";        String str3 = "Strings123";        int result = str1.compareTo( str2 );        System.out.println(result);        result = str2.compareTo( str3 );        System.out.println(result);        result = str3.compareTo( str1 );        System.out.println(result);    }}
    
    0-33
    
  3. compareToIgnoreCase()

    用于按字典顺序比较两个字符串,不考虑大小写。

    • 如果参数字符串等于此字符串,则返回值 0;
    • 如果此字符串小于字符串参数,则返回一个小于 0 的值;
    • 如果此字符串大于字符串参数,则返回一个大于 0 的值。
    public class Test {    public static void main(String args[]) {        String str1 = "STRINGS";        String str2 = "Strings";        String str3 = "Strings123";        int result = str1.compareToIgnoreCase( str2 );        System.out.println(result);        result = str2.compareToIgnoreCase( str3 );        System.out.println(result);        result = str3.compareToIgnoreCase( str1 );        System.out.println(result);     }}
    
    0-33
    
  4. concat()

    用于将指定的字符串参数连接到字符串上。

    image-20210624173946930

  5. contentEquals()

用于将此字符串与指定的 StringBuffer 比较。

public boolean contentEquals(StringBuffer sb)
  • sb -- 要与字符串比较的 StringBuffer。

如字符串与指定 StringBuffer 表示相同的字符序列,则返回 true;否则返回 false。

  1. copyValueOf()

    • public static String copyValueOf(char[] data): 返回指定数组中表示该字符序列的字符串。
    • public static String copyValueOf(char[] data, int offset, int count): 返回指定数组中表示该字符序列的 字符串。
    • data -- 字符数组。
    • offset -- 子数组的初始偏移量。。
    • count -- 子数组的长度。

    返回指定数组中表示该字符序列的字符串。

    public class Test {    public static void main(String args[]) {        char[] Str1 = {'h', 'e', 'l', 'l', 'o', ' ', 'r', 'u', 'n', 'o', 'o', 'b'};        String Str2 = "";        Str2 = Str2.copyValueOf( Str1 );        System.out.println("返回结果:" + Str2);        Str2 = Str2.copyValueOf( Str1, 2, 6 );        System.out.println("返回结果:" + Str2);    }}
    
    返回结果:hello runoob返回结果:llo ru
    
  2. endsWith()

    用于测试字符串是否以指定的后缀结束。

    public boolean endsWith(String suffix)
    
    • suffix -- 指定的后缀。

    如果参数表示的字符序列是此对象表示的字符序列的后缀,则返回 true;否则返回 false。注意,如果参数是空字符串,或者等于此 String 对象(用 equals(Object) 方法确定),则结果为 true。

    public class Test {    public static void main(String args[]) {        String Str = new String("菜鸟教程:www.runoob.com");        boolean retVal;        retVal = Str.endsWith( "runoob" );        System.out.println("返回值 = " + retVal );        retVal = Str.endsWith( "com" );        System.out.println("返回值 = " + retVal );    }}
    
    返回值 = false返回值 = true
    
  3. equals()

    用于将字符串与指定的对象比较。

    public boolean equals(Object anObject)
    
    • anObject -- 与字符串进行比较的对象。

    如果给定对象与字符串相等,则返回 true;否则返回 false。

    public class Test {    public static void main(String args[]) {        String Str1 = new String("runoob");        String Str2 = Str1;        String Str3 = new String("runoob");        boolean retVal;        retVal = Str1.equals( Str2 );        System.out.println("返回值 = " + retVal );        retVal = Str1.equals( Str3 );        System.out.println("返回值 = " + retVal );    }}
    
    返回值 = true返回值 = true
    

    image-20210624175349447

  4. image-20210624183725674

    与equals方法类似 只是忽略大小写

  5. getBytes()

    • getBytes(String charsetName): 使用指定的字符集将字符串编码为 byte 序列,并将结果存储到一个新的 byte 数组中。

    • getBytes(): 使用平台的默认字符集将字符串编码为 byte 序列,并将结果存储到一个新的 byte 数组中。

    • public byte[] getBytes(String charsetName) throws UnsupportedEncodingException或public byte[] getBytes()
      
      import java.io.*;public class Test {    public static void main(String args[]) {        String Str1 = new String("runoob");        try{            byte[] Str2 = Str1.getBytes();            System.out.println("返回值:" + Str2 );            Str2 = Str1.getBytes( "UTF-8" );            System.out.println("返回值:" + Str2 );            Str2 = Str1.getBytes( "ISO-8859-1" );            System.out.println("返回值:" + Str2 );        } catch ( UnsupportedEncodingException e){            System.out.println("不支持的字符集");        }    }}
      
      返回值:[B@7852e922返回值:[B@4e25154f返回值:[B@70dea4e
      
  6. getChars()

    将字符从字符串复制到目标字符数组。

    public void getChars(int srcBegin, int srcEnd, char[] dst,  int dstBegin)
    
    • srcBegin -- 字符串中要复制的第一个字符的索引。
    • srcEnd -- 字符串中要复制的最后一个字符之后的索引。
    • dst -- 目标数组。
    • dstBegin -- 目标数组中的起始偏移量。

    没有返回值,但会抛出 IndexOutOfBoundsException 异常。

    public class Test {    public static void main(String args[]) {        String Str1 = new String("www.runoob.com");        char[] Str2 = new char[6];        try {            Str1.getChars(4, 10, Str2, 0);            System.out.print("拷贝的字符串为:" );            System.out.println(Str2 );        } catch( Exception ex) {            System.out.println("触发异常...");        }    }}
    
    拷贝的字符串为:runoob
    
  7. indexOf()

    • public int indexOf(int ch): 返回指定字符在字符串中第一次出现处的索引,如果此字符串中没有这样的字符,则返回 -1。
    • public int indexOf(int ch, int fromIndex): 返回从 fromIndex 位置开始查找指定字符在字符串中第一次出现处的索引,如果此字符串中没有这样的字符,则返回 -1。
    • int indexOf(String str): 返回指定字符在字符串中第一次出现处的索引,如果此字符串中没有这样的字符,则返回 -1。
    • int indexOf(String str, int fromIndex): 返回从 fromIndex 位置开始查找指定字符在字符串中第一次出现处的索引,如果此字符串中没有这样的字符,则返回 -1。

    image-20210624184511508

    话不多说直接看实例

    public class Main { public static void main(String args[]) {     String string = "aaa456ac";       //查找指定字符是在字符串中的下标。在则返回所在字符串下标;不在则返回-1.       System.out.println(string.indexOf("b")); // indexOf(String str); 返回结果:-1,"b"不存在       // 从第四个字符位置开始往后继续查找,包含当前位置       System.out.println(string.indexOf("a",3));//indexOf(String str, int fromIndex); 返回结果:6       //(与之前的差别:上面的参数是 String 类型,下面的参数是 int 类型)参考数据:a-97,b-98,c-99       // 从头开始查找是否存在指定的字符       System.out.println(string.indexOf(99));//indexOf(int ch);返回结果:7       System.out.println(string.indexOf('c'));//indexOf(int ch);返回结果:7       //从fromIndex查找ch,这个是字符型变量,不是字符串。字符a对应的数字就是97。       System.out.println(string.indexOf(97,3));//indexOf(int ch, int fromIndex); 返回结果:6       System.out.println(string.indexOf('a',3));//indexOf(int ch, int fromIndex); 返回结果:6   }}
    
    -167766
    
    public class Test { public static void main(String args[]) {     String Str = new String("菜鸟教程:www.runoob.com");     String SubStr1 = new String("runoob");     String SubStr2 = new String("com");     System.out.print("查找字符 o 第一次出现的位置 :" );     System.out.println(Str.indexOf( 'o' ));     System.out.print("从第14个位置查找字符 o 第一次出现的位置 :" );     System.out.println(Str.indexOf( 'o', 14 ));     System.out.print("子字符串 SubStr1 第一次出现的位置:" );     System.out.println( Str.indexOf( SubStr1 ));     System.out.print("从第十五个位置开始搜索子字符串 SubStr1 第一次出现的位置 :" );     System.out.println( Str.indexOf( SubStr1, 15 ));     System.out.print("子字符串 SubStr2 第一次出现的位置 :" );     System.out.println(Str.indexOf( SubStr2 )); }}
    
    查找字符 o 第一次出现的位置 :12从第14个位置查找字符 o 第一次出现的位置 :17子字符串 SubStr1 第一次出现的位置:9从第十五个位置开始搜索子字符串 SubStr1 第一次出现的位置 :-1子字符串 SubStr2 第一次出现的位置 :16
    
    1. lastIndexOf()
    • public int lastIndexOf(int ch): 返回指定字符在此字符串中最后一次出现处的索引,如果此字符串中没有这样的字符,则返回 -1。
    • public int lastIndexOf(int ch, int fromIndex): 返回指定字符在此字符串中最后一次出现处的索引,从指定的索引处开始进行反向搜索,如果此字符串中没有这样的字符,则返回 -1。
    • public int lastIndexOf(String str): 返回指定子字符串在此字符串中最右边出现处的索引,如果此字符串中没有这样的字符,则返回 -1。
    • public int lastIndexOf(String str, int fromIndex): 返回指定子字符串在此字符串中最后一次出现处的索引,从指定的索引开始反向搜索,如果此字符串中没有这样的字符,则返回 -1。

    返回值

    指定子字符串在字符串中第一次出现处的索引值。

    就是进行逆向查询 形式大致与indexOf类似

  8. length()

    用于返回字符串的长度。

    空字符串的长度返回 0。

    public class Test {     public static void main(String args[]) {             String Str1 = new String("www.runoob.com");             String Str2 = new String("runoob" );             System.out.print("字符串 Str1 长度 :");             System.out.println(Str1.length());             System.out.print("字符串 Str2 长度 :");             System.out.println(Str2.length());     }}
    
    字符串 Str1 长度 :14字符串 Str2 长度 :6
    
  9. matches()

    用于检测字符串是否匹配给定的正则表达式。

    public boolean matches(String regex)
    
    • regex -- 匹配字符串的正则表达式。

    在字符串匹配给定的正则表达式时,返回 true。

    public class Test {    public static void main(String args[]) {        String Str = new String("www.runoob.com");        System.out.print("返回值 :" );        System.out.println(Str.matches("(.*)runoob(.*)"));        System.out.print("返回值 :" );        System.out.println(Str.matches("(.*)google(.*)"));        System.out.print("返回值 :" );        System.out.println(Str.matches("www(.*)"));    }}
    
    返回值 :true返回值 :false返回值 :true
    
  10. regionMatches()

    用于检测两个字符串在一个区域内是否相等。

    public boolean regionMatches(int toffset,                          String other,                          int ooffset,                          int len)或public boolean regionMatches(boolean ignoreCase,                          int toffset,                          String other,                          int ooffset,                          int len)
    
    • ignoreCase -- 如果为 true,则比较字符时忽略大小写。
    • toffset -- 此字符串中子区域的起始偏移量。
    • other -- 字符串参数。
    • ooffset -- 字符串参数中子区域的起始偏移量。
    • len -- 要比较的字符数。

    如果字符串的指定子区域匹配字符串参数的指定子区域,则返回 true;否则返回 false。是否完全匹配或考虑大小写取决于 ignoreCase 参数。

    public class Test {    public static void main(String args[]) {        String Str1 = new String("www.runoob.com");        String Str2 = new String("runoob");        String Str3 = new String("RUNOOB");        System.out.print("返回值 :" );        System.out.println(Str1.regionMatches(4, Str2, 0, 5));        System.out.print("返回值 :" );        System.out.println(Str1.regionMatches(4, Str3, 0, 5));        System.out.print("返回值 :" );        System.out.println(Str1.regionMatches(true, 4, Str3, 0, 5));    }}
    
    返回值 :true返回值 :false返回值 :true
    
  11. replaceAll()

    使用给定的参数 replacement 替换字符串所有匹配给定的正则表达式的子字符串。

    public String replaceAll(String regex, String replacement)
    
    • regex -- 匹配此字符串的正则表达式。
    • replacement -- 用来替换每个匹配项的字符串。

    成功则返回替换的字符串,失败则返回原始字符串。

    public class Test {    public static void main(String args[]) {        String Str = new String("www.google.com");        System.out.print("匹配成功返回值 :" );        System.out.println(Str.replaceAll("(.*)google(.*)", "runoob" ));        System.out.print("匹配失败返回值 :" );        System.out.println(Str.replaceAll("(.*)taobao(.*)", "runoob" ));    }}
    
    匹配成功返回值 :runoob匹配失败返回值 :www.google.com
    
  12. replaceFirst()………………

    还有很多的类直接去查询java的使用手册

StringBuffer 和 StringBuilder 类

当对字符串进行修改的时候,需要使用 StringBuffer 和 StringBuilder 类。

和 String 类不同的是,StringBuffer 和 StringBuilder 类的对象能够被多次的修改,并且不产生新的未使用对象。

在使用 StringBuffer 类时,每次都会对 StringBuffer 对象本身进行操作,而不是生成新的对象,所以如果需要对字符串进行修改推荐使用 StringBuffer。

StringBuilder 类在 Java 5 中被提出,它和 StringBuffer 之间的最大不同在于 StringBuilder 的方法不是线程安全的(不能同步访问)。

由于 StringBuilder 相较于 StringBuffer 有速度优势,所以多数情况下建议使用 StringBuilder 类。

public class RunoobTest{    public static void main(String args[]){        StringBuilder sb = new StringBuilder(10);        sb.append("Runoob..");        System.out.println(sb);          sb.append("!");        System.out.println(sb);         sb.insert(8, "Java");        System.out.println(sb);         sb.delete(5,8);        System.out.println(sb);      }}
Runoob..Runoob..!Runoob..Java!RunooJava!
StringBuffer 方法

image-20210624193225290

数组

声明数组

dataType[] arrayRefVar;   // 首选的方法 或 dataType arrayRefVar[];  // 效果相同,但不是首选方法

创建数组

image-20210624193734776

For-Each循环 遍历数组

image-20210624193916374

image-20210624194012976

image-20210624194050795

Array类

image-20210624194507746

日期时间

直接上实例import java.util.Date;  public class DateDemo {   public static void main(String args[]) {       // 初始化 Date 对象       Date date = new Date();               // 使用 toString() 函数显示日期时间       System.out.println(date.toString());   }}
Mon May 04 09:51:52 CDT 2013
日期比较

image-20210624194847755

使用 SimpleDateFormat 格式化日期

SimpleDateFormat 是一个以语言环境敏感的方式来格式化和分析日期的类。SimpleDateFormat 允许你选择任何用户自定义日期时间格式来运行。

import  java.util.*;import java.text.*; public class DateDemo {   public static void main(String args[]) {       Date dNow = new Date( );      SimpleDateFormat ft = new SimpleDateFormat ("yyyy-MM-dd hh:mm:ss");       System.out.println("当前时间为: " + ft.format(dNow));   }}
SimpleDateFormat ft = new SimpleDateFormat ("yyyy-MM-dd hh:mm:ss");

这一行代码确立了转换的格式,其中 yyyy 是完整的公元年,MM 是月份,dd 是日期,HH:mm:ss 是时、分、秒。注意:有的格式大写,有的格式小写,例如 MM 是月份,mm 是分;HH 是 24 小时制,而 hh 是 12 小时制。

Java 休眠(sleep)

sleep()使当前线程进入停滞状态(阻塞当前线程),让出CPU的使用、目的是不让当前线程独自霸占该进程所获的CPU资源,以留一定时间给其他线程执行的机会。

import java.util.*;public class SleepDemo {public static void main(String args[]) {   try {       System.out.println(new Date( ) + "\n");       Thread.sleep(1000*3);   // 休眠3秒      System.out.println(new Date( ) + "\n");    } catch (Exception e) {        System.out.println("Got an exception!");    }}}
Thu Sep 17 10:20:30 CST 2015Thu Sep 17 10:20:33 CST 2015
Calendar类

Calendar类的功能要比Date类强大很多,而且在实现方式上也比Date类要复杂一些。

Calendar类是一个抽象类,在实际使用时实现特定的子类的对象,创建对象的过程对程序员来说是透明的,只需要使用getInstance方法创建即可。

Calendar c = Calendar.getInstance();//默认是当前日期
//创建一个代表2009年6月12日的Calendar对象Calendar c1 = Calendar.getInstance();c1.set(2009, 6 - 1, 12);

Java 流(Stream)、文件(File)和IO

Java.io 包几乎包含了所有操作输入、输出需要的类。所有这些流类代表了输入源和输出目标。

Java.io 包中的流支持很多种格式,比如:基本类型、对象、本地化字符集等等。

一个流可以理解为一个数据的序列。输入流表示从一个源读取数据,输出流表示向一个目标写数据。

读取控制台输入

Java 的控制台输入由 System.in 完成。

为了获得一个绑定到控制台的字符流,你可以把 System.in 包装在一个 BufferedReader 对象中来创建一个字符流。

BufferedReader br = new BufferedReader(new                    InputStreamReader(System.in));

BufferedReader 对象创建后,我们便可以使用 read() 方法从控制台读取一个字符,或者用 readLine() 方法读取一个字符串。

从控制台读取多字符输入

从 BufferedReader 对象读取一个字符要使用 read() 方法,它的语法如下:

int read( ) throws IOException
//使用 BufferedReader 在控制台读取字符import java.io.*;public class BRRead {    public static void main(String[] args) throws IOException {        char c;        // 使用 System.in 创建 BufferedReader        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));        System.out.println("输入字符, 按下 'q' 键退出。");        // 读取字符        do {            c = (char) br.read();            System.out.println(c);        } while (c != 'q');    }}

用 read() 方法从控制台不断读取字符直到用户输入 q

输入字符, 按下 'q' 键退出。runoobrunoobqq

从控制台读取字符串

String readLine( ) throws IOException
//使用 BufferedReader 在控制台读取字符import java.io.*;public class BRReadLines { public static void main(String[] args) throws IOException {     // 使用 System.in 创建 BufferedReader     BufferedReader br = new BufferedReader(new InputStreamReader(System.in));     String str;     System.out.println("Enter lines of text.");     System.out.println("Enter 'end' to quit.");     do {         str = br.readLine();         System.out.println(str);     } while (!str.equals("end")); }}
Enter lines of text.Enter 'end' to quit.This is line oneThis is line oneThis is line twoThis is line twoendend

控制台输出

PrintStream 继承了 OutputStream类,并且实现了方法 write()。这样,write() 也可以用来往控制台写操作。

void write(int byteval)

import java.io.*;//演示 System.out.write().public class WriteDemo { public static void main(String[] args) {     int b;     b = 'A';     System.out.write(b);     System.out.write('\n'); }}

读写文件

一个流被定义为一个数据序列。输入流用于从源读取数据,输出流用于向目标写数据。

FileInputStream

该流用于从文件读取数据,它的对象可以用关键字 new 来创建。

可以使用字符串类型的文件名来创建一个输入流对象来读取文件:

InputStream f = new FileInputStream("C:/java/hello");

也可以使用一个文件对象来创建一个输入流对象来读取文件。我们首先得使用 File() 方法来创建一个文件对象:

File f = new File("C:/java/hello");InputStream in = new FileInputStream(f);

image-20210624202233132

FileOutputStream

该类用来创建一个文件并向文件中写数据。

如果该流在打开文件进行输出前,目标文件不存在,那么该流会创建该文件。

有两个构造方法可以用来创建 FileOutputStream 对象。

OutputStream f = new FileOutputStream("C:/java/hello")

也可以使用一个文件对象来创建一个输出流来写文件。我们首先得使用File()方法来创建一个文件对象:

File f = new File("C:/java/hello");OutputStream fOut = new FileOutputStream(f);

image-20210624202455046

文件和I/O

Java File类

Java文件类以抽象的方式代表文件名和目录路径名。该类主要用于文件和目录的创建、文件的查找和文件的删除等。

File对象代表磁盘中实际存在的文件和目录。通过以下构造方法创建一个File对象。

image-20210624202803215

import java.io.File;public class DirList { public static void main(String args[]) {     String dirname = "/java";     File f1 = new File(dirname);     if (f1.isDirectory()) {         System.out.println("Directory of " + dirname);         String s[] = f1.list();         for (int i = 0; i < s.length; i++) {             File f = new File(dirname + "/" + s[i]);             if (f.isDirectory()) {                 System.out.println(s[i] + " is a directory");             } else {                 System.out.println(s[i] + " is a file");             }         }     } else {         System.out.println(dirname + " is not a directory");     } }}
Directory of /javabin is a directorylib is a directorydemo is a directorytest.txt is a fileREADME is a fileindex.html is a fileinclude is a directory
Java FileReader类

FileReader类从InputStreamReader类继承而来。该类按字符读取流中数据。可以通过以下几种构造方法创建需要的对象。

在给定从中读取数据的 File 的情况下创建一个新 FileReader。

FileReader(File file)

image-20210624203050615

image-20210624203109946

import java.io.*;public class FileRead { public static void main(String args[]) throws IOException {     File file = new File("Hello1.txt");     // 创建文件     file.createNewFile();     // creates a FileWriter Object     FileWriter writer = new FileWriter(file);     // 向文件写入内容     writer.write("This\n is\n an\n example\n");     writer.flush();     writer.close();     // 创建 FileReader 对象     FileReader fr = new FileReader(file);     char[] a = new char[50];     fr.read(a); // 读取数组中的内容     for (char c : a)         System.out.print(c); // 一个一个打印字符     fr.close(); }}
Thisisanexample
Java FileWriter类

FileWriter 类从 OutputStreamWriter 类继承而来。该类按字符向流中写入数据。可以通过以下几种构造方法创建需要的对象。

在给出 File 对象的情况下构造一个 FileWriter 对象。

FileWriter(File file)

在给出 File 对象的情况下构造一个 FileWriter 对象。

FileWriter(File file, boolean append)
  • file:要写入数据的 File 对象。
  • append:如果 append 参数为 true,则将字节写入文件末尾处,相当于追加信息。如果 append 参数为 false, 则写入文件开始处。
import java.io.*;public class FileRead {    public static void main(String args[]) throws IOException {        File file = new File("Hello1.txt");        // 创建文件        file.createNewFile();        // creates a FileWriter Object        FileWriter writer = new FileWriter(file);        // 向文件写入内容        writer.write("This\n is\n an\n example\n");        writer.flush();        writer.close();        // 创建 FileReader 对象        FileReader fr = new FileReader(file);        char[] a = new char[50];        fr.read(a); // 从数组中读取内容        for (char c : a)            System.out.print(c); // 一个个打印字符        fr.close();    }}
Thisisanexample

Java Scanner 类

java.util.Scanner 是 Java5 的新特征,我们可以通过 Scanner 类来获取用户的输入。

Scanner s = new Scanner(System.in);

并通过 Scanner 类的 next() 与 nextLine() 方法获取输入的字符串,在读取前我们一般需要 使用 hasNext 与 hasNextLine 判断是否还有输入的数据:

import java.util.Scanner; public class ScannerDemo { public static void main(String[] args) {     Scanner scan = new Scanner(System.in);     // 从键盘接收数据     // next方式接收字符串     System.out.println("next方式接收:");     // 判断是否还有输入     if (scan.hasNext()) {         String str1 = scan.next();         System.out.println("输入的数据为:" + str1);     }     scan.close(); }}
next() 与 nextLine() 区别

image-20210624203841962

如果要输入 int 或 float 类型的数据,在 Scanner 类中也有支持,但是在输入之前最好先使用 hasNextXxx() 方法进行验证,再使用 nextXxx() 来读取:

import java.util.Scanner; public class ScannerDemo {    public static void main(String[] args) {        Scanner scan = new Scanner(System.in);        // 从键盘接收数据        int i = 0;        float f = 0.0f;        System.out.print("输入整数:");        if (scan.hasNextInt()) {            // 判断输入的是否是整数            i = scan.nextInt();            // 接收整数            System.out.println("整数数据:" + i);        } else {            // 输入错误的信息            System.out.println("输入的不是整数!");        }        System.out.print("输入小数:");        if (scan.hasNextFloat()) {            // 判断输入的是否是小数            f = scan.nextFloat();            // 接收小数            System.out.println("小数数据:" + f);        } else {            // 输入错误的信息            System.out.println("输入的不是小数!");        }        scan.close();    }}
$ javac ScannerDemo.java$ java ScannerDemo输入整数:12整数数据:12输入小数:1.2小数数据:1.2

以下实例我们可以输入多个数字,并求其总和与平均数,每输入一个数字用回车确认,通过输入非数字来结束输入并输出执行结果:

import java.util.Scanner; class RunoobTest {    public static void main(String[] args) {        System.out.println("请输入数字:");        Scanner scan = new Scanner(System.in);         double sum = 0;        int m = 0;         while (scan.hasNextDouble()) {            double x = scan.nextDouble();            m = m + 1;            sum = sum + x;        }         System.out.println(m + "个数的和为" + sum);        System.out.println(m + "个数的平均值是" + (sum / m));        scan.close();    }}
$ javac ScannerDemo.java$ java ScannerDemo请输入数字:12231521.4end4个数的和为71.44个数的平均值是17.85

Java 异常处理

异常是程序中的一些错误,但并不是所有的错误都是异常,并且错误有时候是可以避免的。

比如说,你的代码少了一个分号,那么运行出来结果是提示是错误 java.lang.Error;如果你用System.out.println(11/0),那么你是因为你用0做了除数,会抛出 java.lang.ArithmeticException 的异常。

  • 用户输入了非法数据。
  • 要打开的文件不存在。
  • 网络通信时连接中断,或者JVM内存溢出。
捕获异常

使用 try 和 catch 关键字可以捕获异常。try/catch 代码块放在异常可能发生的地方。

try/catch代码块中的代码称为保护代码,使用 try/catch 的语法如下:

try{// 程序代码}catch(ExceptionName e1){//Catch 块}

Catch 语句包含要捕获异常类型的声明。当保护代码块中发生一个异常时,try 后面的 catch 块就会被检查。

如果发生的异常包含在 catch 块中,异常会被传递到该 catch 块,这和传递一个参数到方法是一样。

image-20210624204450604

多重捕获块

image-20210624204531657

throws/throw 关键字:

image-20210624204612896

finally关键字

image-20210624204735166

  • catch 不能独立于 try 存在。
  • 在 try/catch 后面添加 finally 块并非强制性要求的。
  • try 代码后不能既没 catch 块也没 finally 块。
  • try, catch, finally 块之间不能添加任何代码。

Java 继承

类的继承格式
class 父类 {} class 子类 extends 父类 {}
继承的特性
  • 子类拥有父类非 private 的属性、方法。
  • 子类可以拥有自己的属性和方法,即子类可以对父类进行扩展。
  • 子类可以用自己的方式实现父类的方法。
  • Java 的继承是单继承,但是可以多重继承,单继承就是一个子类只能继承一个父类,多重继承就是,例如 B 类继承 A 类,C 类继承 B 类,所以按照关系就是 B 类是 C 类的父类,A 类是 B 类的父类,这是 Java 继承区别于 C++ 继承的一个特性。
  • 提高了类之间的耦合性(继承的缺点,耦合度高就会造成代码之间的联系越紧密,代码独立性越差)。
继承关键字

继承可以使用 extends 和 implements 这两个关键字来实现继承,而且所有的类都是继承于 java.lang.Object,当一个类没有继承的两个关键字,则默认继承object(这个类在 java.lang 包中,所以不需要 import)祖先类。

extends关键字

在 Java 中,类的继承是单一继承,也就是说,一个子类只能拥有一个父类,所以 extends 只能继承一个类。

implements关键字

使用 implements 关键字可以变相的使java具有多继承的特性,使用范围为类继承接口的情况,可以同时继承多个接口(接口跟接口之间采用逗号分隔)。

public interface A { public void eat(); public void sleep();}public interface B { public void show();}public class C implements A,B {}
super 与 this 关键字

super关键字:我们可以通过super关键字来实现对父类成员的访问,用来引用当前对象的父类。

this关键字:指向自己的引用。

class Animal {void eat() { System.out.println("animal : eat");}}class Dog extends Animal {void eat() { System.out.println("dog : eat");}void eatTest() { this.eat();   // this 调用自己的方法 super.eat();  // super 调用父类方法}}public class Test {public static void main(String[] args) { Animal a = new Animal(); a.eat(); Dog d = new Dog(); d.eatTest();}}
animal : eatdog : eatanimal : eat
final关键字

final 关键字声明类可以把类定义为不能继承的,即最终类;或者用于修饰方法,该方法不能被子类重写:

image-20210624210120923

实例变量也可以被定义为 final,被定义为 final 的变量不能被修改。被声明为 final 类的方法自动地声明为 final,但是实例变量并不是 final

构造器

子类是不继承父类的构造器(构造方法或者构造函数)的,它只是调用(隐式或显式)。如果父类的构造器带有参数,则必须在子类的构造器中显式地通过 super 关键字调用父类的构造器并配以适当的参数列表。

如果父类构造器没有参数,则在子类的构造器中不需要使用 super 关键字调用父类构造器,系统会自动调用父类的无参构造器。

class SuperClass {private int n;SuperClass(){ System.out.println("SuperClass()");}SuperClass(int n) { System.out.println("SuperClass(int n)"); this.n = n;}}// SubClass 类继承class SubClass extends SuperClass{private int n;SubClass(){ // 自动调用父类的无参数构造器 System.out.println("SubClass");}  public SubClass(int n){  super(300);  // 调用父类中带有参数的构造器 System.out.println("SubClass(int n):"+n); this.n = n;}}// SubClass2 类继承class SubClass2 extends SuperClass{private int n;SubClass2(){ super(300);  // 调用父类中带有参数的构造器 System.out.println("SubClass2");}  public SubClass2(int n){ // 自动调用父类的无参数构造器 System.out.println("SubClass2(int n):"+n); this.n = n;}}public class TestSuperSub{public static void main (String args[]){ System.out.println("------SubClass 类继承------"); SubClass sc1 = new SubClass(); SubClass sc2 = new SubClass(100);  System.out.println("------SubClass2 类继承------"); SubClass2 sc3 = new SubClass2(); SubClass2 sc4 = new SubClass2(200); }}
------SubClass 类继承------SuperClass()SubClassSuperClass(int n)SubClass(int n):100------SubClass2 类继承------SuperClass(int n)SubClass2SuperClass()SubClass2(int n):200

Java 重写(Override)与重载(Overload)

重写(Override)

重写是子类对父类的允许访问的方法的实现过程进行重新编写, 返回值和形参都不能改变。即外壳不变,核心重写!

重写的好处在于子类可以根据需要,定义特定于自己的行为。 也就是说子类能够根据需要实现父类的方法。

重写方法不能抛出新的检查异常或者比被重写方法申明更加宽泛的异常。例如: 父类的一个方法申明了一个检查异常 IOException,但是在重写这个方法的时候不能抛出 Exception 异常,因为 Exception 是 IOException 的父类,只能抛出 IOException 的子类异常。

方法的重写规则

  • 参数列表与被重写方法的参数列表必须完全相同。
  • 返回类型与被重写方法的返回类型可以不相同,但是必须是父类返回值的派生类(java5 及更早版本返回类型要一样,java7 及更高版本可以不同)。
  • 访问权限不能比父类中被重写的方法的访问权限更低。例如:如果父类的一个方法被声明为 public,那么在子类中重写该方法就不能声明为 protected。
  • 父类的成员方法只能被它的子类重写。
  • 声明为 final 的方法不能被重写。
  • 声明为 static 的方法不能被重写,但是能够被再次声明。
  • 子类和父类在同一个包中,那么子类可以重写父类所有方法,除了声明为 private 和 final 的方法。
  • 子类和父类不在同一个包中,那么子类只能够重写父类的声明为 public 和 protected 的非 final 方法。
  • 重写的方法能够抛出任何非强制异常,无论被重写的方法是否抛出异常。但是,重写的方法不能抛出新的强制性异常,或者比被重写方法声明的更广泛的强制性异常,反之则可以。
  • 构造方法不能被重写。
  • 如果不能继承一个类,则不能重写该类的方法。

Super 关键字的使用

当需要在子类中调用父类的被重写方法时,要使用 super 关键字。

class Animal{public void move(){   System.out.println("动物可以移动");}}class Dog extends Animal{public void move(){   super.move(); // 应用super类的方法   System.out.println("狗可以跑和走");}}public class TestDog{public static void main(String args[]){   Animal b = new Dog(); // Dog 对象   b.move(); //执行 Dog类的方法}}
动物可以移动狗可以跑和走

重载(Overload)

重载(overloading) 是在一个类里面,方法名字相同,而参数不同。返回类型可以相同也可以不同。

每个重载的方法(或者构造函数)都必须有一个独一无二的参数类型列表。

最常用的地方就是构造器的重载。

  • 被重载的方法必须改变参数列表(参数个数或类型不一样);
  • 被重载的方法可以改变返回类型;
  • 被重载的方法可以改变访问修饰符;
  • 被重载的方法可以声明新的或更广的检查异常;
  • 方法能够在同一个类中或者在一个子类中被重载。
  • 无法以返回值类型作为重载函数的区分标准。

image-20210624211850583

image-20210624212036868

重载就是同样的一个方法能够根据输入数据的不同,做出不同的处理

重写就是当子类继承自父类的相同方法,输入数据一样,但要做出有别于父类的响应时,你就要覆盖父类方法

Java 多态

多态是同一个行为具有多个不同表现形式或形态的能力。

多态就是同一个接口,使用不同的实例而执行不同操作.

多态的优点

  • \1. 消除类型之间的耦合关系
  • \2. 可替换性
  • \3. 可扩充性
  • \4. 接口性
  • \5. 灵活性
  • \6. 简化性
多态存在的三个必要条件
  • 继承
  • 重写
  • 父类引用指向子类对象:Parent p = new Child();
public class Test { public static void main(String[] args) {   show(new Cat());  // 以 Cat 对象调用 show 方法   show(new Dog());  // 以 Dog 对象调用 show 方法   Animal a = new Cat();  // 向上转型     a.eat();               // 调用的是 Cat 的 eat   Cat c = (Cat)a;        // 向下转型     c.work();        // 调用的是 Cat 的 work}   public static void show(Animal a)  {   a.eat();       // 类型判断     if (a instanceof Cat)  {  // 猫做的事情          Cat c = (Cat)a;           c.work();       } else if (a instanceof Dog) { // 狗做的事情          Dog c = (Dog)a;           c.work();       }   }  }abstract class Animal {   abstract void eat();  }  class Cat extends Animal {   public void eat() {       System.out.println("吃鱼");   }   public void work() {       System.out.println("抓老鼠");   }  }  class Dog extends Animal {   public void eat() {       System.out.println("吃骨头");   }   public void work() {       System.out.println("看家");   }  }
吃鱼抓老鼠吃骨头看家吃鱼抓老鼠

Java 抽象类

在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。

抽象类除了不能实例化对象之外,类的其它功能依然存在,成员变量、成员方法和构造方法的访问方式和普通类一样。

由于抽象类不能实例化对象,所以抽象类必须被继承,才能被使用。也是因为这个原因,通常在设计阶段决定要不要设计抽象类。

父类包含了子类集合的常见的方法,但是由于父类本身是抽象的,所以不能使用这些方法。

在Java中抽象类表示的是一种继承关系,一个类只能继承一个抽象类,而一个类却可以实现多个接口。

抽象类

使用abstract class来定义抽象类。

继承抽象类

/* 文件名 : Salary.java */public class Salary extends Employee{private double salary; //Annual salarypublic Salary(String name, String address, int number, double   salary){    super(name, address, number);    setSalary(salary);}public void mailCheck(){    System.out.println("Within mailCheck of Salary class ");    System.out.println("Mailing check to " + getName()       + " with salary " + salary);   }   public double getSalary()   {       return salary;   }   public void setSalary(double newSalary)   {       if(newSalary >= 0.0)       {          salary = newSalary;       }   }   public double computePay()   {      System.out.println("Computing salary pay for " + getName());      return salary/52;   }}
/* 文件名 : AbstractDemo.java */public class AbstractDemo{   public static void main(String [] args)   {      Salary s = new Salary("Mohd Mohtashim", "Ambehta, UP", 3, 3600.00);      Employee e = new Salary("John Adams", "Boston, MA", 2, 2400.00);      System.out.println("Call mailCheck using Salary reference --");      s.mailCheck();      System.out.println("\n Call mailCheck using Employee reference--");      e.mailCheck();    }}
Constructing an EmployeeConstructing an EmployeeCall mailCheck using  Salary reference --Within mailCheck of Salary classMailing check to Mohd Mohtashim with salary 3600.0Call mailCheck using Employee reference--Within mailCheck of Salary classMailing check to John Adams with salary 2400.

抽象方法

Abstract 关键字同样可以用来声明抽象方法,抽象方法只包含一个方法名,而没有方法体。

抽象方法没有定义,方法名后面直接跟一个分号,而不是花括号。

public abstract class Employee{   private String name;   private String address;   private int number;      public abstract double computePay();      //其余代码}
  • 如果一个类包含抽象方法,那么该类必须是抽象类。
  • 任何子类必须重写父类的抽象方法,或者声明自身为抽象类。

继承抽象方法的子类必须重写该方法。否则,该子类也必须声明为抽象类。最终,必须有子类实现该抽象方法,否则,从最初的父类到最终的子类都不能用来实例化对象。

抽象类总结规定

  • \1. 抽象类不能被实例化(初学者很容易犯的错),如果被实例化,就会报错,编译无法通过。只有抽象类的非抽象子类可以创建对象。
  • \2. 抽象类中不一定包含抽象方法,但是有抽象方法的类必定是抽象类。
  • \3. 抽象类中的抽象方法只是声明,不包含方法体,就是不给出方法的具体实现也就是方法的具体功能。
  • \4. 构造方法,类方法(用 static 修饰的方法)不能声明为抽象方法。
  • \5. 抽象类的子类必须给出抽象类中的抽象方法的具体实现,除非该子类也是抽象类。

抽象类和接口的区别

1、语法层面上的区别
  • 1)抽象类可以提供成员方法的实现细节,而接口中只能存在public abstract 方法;
  • 2)抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是public static final类型的;
  • 3)接口中不能含有静态代码块以及静态方法,而抽象类可以有静态代码块和静态方法;
  • 4)一个类只能继承一个抽象类,而一个类却可以实现多个接口。

Java 接口

接口通常以interface来声明。一个类通过继承接口的方式,从而来继承接口的抽象方法。

接口并不是类,编写接口的方式和类很相似,但是它们属于不同的概念。类描述对象的属性和方法。接口则包含类要实现的方法。

除非实现接口的类是抽象类,否则该类要定义接口中的所有方法。

接口无法被实例化,但是可以被实现。一个实现接口的类,必须实现接口内所描述的所有方法,否则就必须声明为抽象类。另外,在 Java 中,接口类型可用来声明一个变量,他们可以成为一个空指针,或是被绑定在一个以此接口实现的对象。

接口与类的区别:

  • 接口不能用于实例化对象。
  • 接口没有构造方法。
  • 接口中所有的方法必须是抽象方法。
  • 接口不能包含成员变量,除了 static 和 final 变量。
  • 接口不是被类继承了,而是要被类实现。
  • 接口支持多继承。

接口的声明

interface 接口名称 [extends 其他的接口名] {     // 声明变量     // 抽象方法}

Interface关键字用来声明一个接口。下面是接口声明的一个简单例子。

/* 文件名 : NameOfInterface.java */import java.lang.*;//引入包public interface NameOfInterface{//任何类型 final, static 字段//抽象方法
  • 接口是隐式抽象的,当声明一个接口的时候,不必使用abstract关键字。
  • 接口中每一个方法也是隐式抽象的,声明时同样不需要abstract关键字。
  • 接口中的方法都是公有的。

接口的实现

当类实现接口的时候,类要实现接口中所有的方法。否则,类必须声明为抽象的类。

类使用implements关键字实现接口。在类声明中,Implements关键字放在class声明后面。

...implements 接口名称[, 其他接口名称, 其他接口名称..., ...] ...

public class MammalInt implements Animal{public void eat(){   System.out.println("Mammal eats");}public void travel(){   System.out.println("Mammal travels");} public int noOfLegs(){   return 0;}public static void main(String args[]){   MammalInt m = new MammalInt();   m.eat();   m.travel();}}
Mammal eatsMammal travels

Java 枚举(enum)

java 枚举是一个特殊的类,一般表示一组常量,比如一年的 4 个季节,一个年的 12 个月份,一个星期的 7 天,方向有东南西北等。

Java 枚举类使用 enum 关键字来定义,各个常量使用逗号 , 来分割。

enum Color {     RED, GREEN, BLUE; } 
enum Color{    RED, GREEN, BLUE;} public class Test{    // 执行输出结果    public static void main(String[] args)    {        Color c1 = Color.RED;        System.out.println(c1);    }}
RED

每个枚举都是通过 Class 在内部实现的,且所有的枚举值都是 public static final 的。

Java 多线程编程

posted @ 2021-06-25 17:58  云吞豚  阅读(69)  评论(0)    收藏  举报