重拾java

标识符、HelloWorld

/*
   标识符
   Java中,自己定义的内容
   标识符的规则:
     组成: 字母52个A-Z a-z 数字0-9 _ 下划线 $ 美元符

   注意: 不能数字开头,不能是关键字

   定义名字:
      _abc  0a  a0  a#a  a$a   void
     YES  NO  YES NO   YES   NO

     类的名字: 首字母大写,第二个单词首字母大写
    BeiJingShiHaiDianQuYiYuan
    MeiGuoJiaLiFuNiYa

   方法的名字:首字母小写,每个单词首字母大写
     addStudent
*/
public class Demo{
  public static void main(String[] args) {
    int _Class;
  }
}
/*
     实现了一个Java的HelloWorld程序
   实现步骤:
     1. 定义类
     2. 定义主方法
     3. 一条命令,控制台输出了HelloWorld
*/
public class HelloWorld{
  //main主方法,固定格式,程序的入口点
  public static void main(String[] args){
    //系统 输出 打印    打印的内容
    System.out.println("HelloWorld");
  }
}

变量、数据类型、运算符

1.什么是变量?变量的定义格式?要使用变量需要注意什么?
就是可变的量
数据类型 变量名 = 数值;
同一范围内不能重复定义
不赋值不能使用

2.Java中的数据类型分几类?基本数据类型有哪些?
两大类
 基本数据类型
  byte(1) short(2) int(4) long(8) float(4) double(6) char(2) boolean(1)
 引用数据类型
  类 接口 数组 枚举

3.数据类型转换:
 隐式转换:由低级专向高级
 强制转换:由高级专向低级

 面试题:
 第一题:
 byte b1=3,b2=4,b;
 b=b1+b2;//错误 因为他们最终是要转向int类型 而int类型的值不能赋值给byte
 b=3+4;//正确 因为他们都是常量 具有常量类型优化机制 可以直接识别为byte
 哪句是编译失败的呢?为什么呢?

 第二题:
 byte by = 130;有没有问题?有问题如何解决?结果是多少呢?
 有问题 因为这个数超出了byte的取值范围 要用byte类型进行强制转换 结果是-126

 第三题:
 byte b = 10;
 b++;
 b = b + 1;//失败 因为在和一个int类型的常量进行相加的时候b自动转换成int类型 而一个int类型的数据是没办法直接赋值给byte类型的变量的
 哪句是编译失败的呢?为什么呢?

4.常见的算术运算符有哪些?
 答:+ - * / %
 (1)+运算符的作用有哪些?
  可以作为数学运算符 也可用作字符串拼接符
 (2)除法和取余的区别?
  除法是数学运算机型相初操作 取余数运算符是对除法操作之后取其余数进行操作的
 (3)++和–的使用规则?
  分别为自增 自减 在放在 变量前面就是先进行运算放在后面就是后进行运算

5.常见的赋值运算符有哪些?
 答:= += -= *= /= %=
 (1)+=运算的作用是什么?
  a += b;== a = a + b;
 (2)扩展的赋值运算符有什么特点?
  会进行自动强制数据类型转换

6.看程序说结果,请不要提前运行?

  public class Test1 {
    public static void main(String[] args) {
       int x = 4;
       int y = (--x)+(x--)+(x*10);//26
       System.out.println("x = " + x + ",y = " + y);
    }
  }/*x = 2 y = 26*/

基本数据类型包装类,装箱、拆箱

包装类
把基本数据类型成员变量看作对象可以进行一些操作
int->Integer
byte->Byte
……
装箱、拆箱

JDK1.5后出现的新特性,自动装箱和自动拆箱
自动装箱:基本数据类型,直接变成对象
Integer in = 1;//Integer in = new Integer(1)
自动拆箱:对象中的数据变回基本数据类型
in = in + 1;//in = in.inValue + 1

为循环起名、使用引用数据类型(Random、Scanner)

break

a:for(int i = 0 ; i < 2; i++){
for(int j = 0; j < 5 ;j++){
System.out.print(“j=”+j);
break a;
}
System.out.println(“i=”+i);
}
给循环命名, 可在任意子循环中跳出或者结束指定循环

Random

/*
    java中已经有的引用类型  Random类,作用,产生随机数
  步骤:
    1. 导入包, Random类,也在java.util文件夹
    2. 公式: 创建出Random类型的变量
    3. 变量. 调用Random类中的功能,产生随机数

    Random类,提供功能 , 名字  nextInt() 产生一个随机数, 结果是int类型
    出现随机数的范围, 在功能nextInt(写一个整数), 整数: 随机出来的范围
    随机数的范围在  0 - 指定的整数之间的随机数   nextInt(100)   0-99

    产生浮点的随机数: 功能名字 nextDouble()  随机数的范围 0.0-1.0

    随机数: 伪随机数, 虚拟机根据人写好的一个算法,生成出来的
*/
import java.util.Random;
public class RandomDemo{
  public static void main(String[] args){
     // 2. 公式: 创建出Random类型的变量
     Random ran = new Random();
     // 3. 变量. 调用Random类中的功能,产生随机数
     // Random类中的,产生随机数的功能
     int i = ran.nextInt(100);
     System.out.println(i);

     //问题? 产生随机数,范围 1-100之间
     // nextInt(100) 0-99 + 1

     double d = ran.nextDouble();
     System.out.println(d);
  }
}

Scanner

/*
  引用数据类型, 介绍一个类  Scanner
  java已经存在了,是Sun公司为我们做好的类,使用他
  定义引用数据类型变量,和基本类型变量区别
    int a = 1;
  格式:
    类型  变量名 = new 类型();
  举例: 创建出Scanner类的变量

    Scanner sc = new Scanner();
    int a = 1;
  每个引用类型,都有自己的功能,如何使用功能
  公式:
    变量.功能名字()

  Scanner类,作用,让我在命令行中,接受键盘的输入
  使用Scanner类步骤:
    1. 导入包,指明类所在的文件夹, 关键字 import
       java文件夹-util文件夹
    2. 公式,创建出Scanner类型变量
    3. 变量.使用Scanner类中的功能,完成键盘输入
*/
import java.util.Scanner;
public class ScannerDemo{
  public static void main(String[] args){
    // 类型  变量名 = new 类型();
    // 创建出Scanner,类变量
    Scanner sc = new Scanner(System.in);
    //变量.功能名字() 接受键盘输入
    // 功能: nextInt() 接受键盘输入,保证输入的是整数
    // 功能接受的数据就是整数,功能运行后的结果就是整数类型
    int i = sc.nextInt();
    System.out.println(i);

    //Scanner类的另一个功能    next() 接受键盘输入的字符串

    String s = sc.next();
    System.out.println(s);
  }
}

数组、switch

/*
    定义数组容器
   定义数组容器,要素,强制数据类型的语言
   必须有数据类型, 大小, 就是存储数据的个数
   定义数组公式:
     数据类型[] 变量名 = new 数据类型[存储元素的个数];

      数据类型: 数组中存储元素的数据类型
      [] 表示数组的意思
      变量名  自定义标识符

      new  创建容器关键字
      数据类型: 数组中存储元素的数据类型
      []  表示数组的意思
      元素个数,就是数组中,可以存储多少个数据 (恒定, 定长)

    数组是一个容器: 存储到数组中的每个元素,都有自己的自动编号
    自动编号,最小值是0, 最大值,长度-1
    自动编号专业名次, 索引(index), 下标, 角标
    访问数组存储的元素,必须依赖于索引, 公式 数组名[索引]

    Java提供一个属性,操作索引的
    数组的一个属性,就是数组的长度, 属性的名字 length
    使用属性:  数组名.length  数据类型 int

    数组的最小索引是0, 最大索引数组.length-1

    数组的两个定义方式
      数据类型[]  变量名 = new 数据类型[]{元素1,元素2,元素3};
      注意事项: new 后面的中括号中,不允许写任何内容,写了就编译失败

      数据类型[]  变量名 = {元素1,元素2,元素3};
*/
public class ArrayDemo{
  public static void main(String[] args){
    //定义数组,存储整数,容器长度, 3个
    // 数据类型[] 变量名 = new 数据类型[存储元素的个数];
    int[] arr = new int[3];
    System.out.println(arr);

    //通过索引的方式,数组中的三个元素
    System.out.println(arr[0]);
    System.out.println(arr[1]);
    System.out.println(arr[2]);
    System.out.println(arr.length);
  }
}

二维数组

/*
    二维数组
    数组中的数组,数组里面存储的还是数组

  定义方式和一维数组很相似

  int[][] arr = new int[3][4];
  定义一个二维数组
  [3]  表示: 二维数组中,有三个一维数组
  [4]  表示: 三个一维数组中,每个数组的长度是4

  最简单的二维数组定义方式
     int[][] arr = { {1,4} ,{3,6,8}, {0,9,8} };
*/
public class ArrayArrayDemo{
  public static void main(String[] args){
    int[][] arr = new int[3][4];
    System.out.println(arr);

    System.out.println(arr[1]);
    System.out.println(arr[2][3]);
  }
}

switch

选择语句 switch语句
编写格式
swtich(表达式){
case 常量1 :
要执行的语句;
break;
case 常量2 :
要执行的语句;
break;
case 常量3 :
要执行的语句;
break;
default:
要执行的语句;
break;
}
执行流程: 表达式,和case后面的常量进行比较
和哪个case后的常量相同,就执行哪个case后面的程序,遇到break,就全结束
关键字: switch case default break
switch语句中的表达式的数据类型,是有要求的
JDK1.0 - 1.4 数据类型接受 byte short int char
JDK1.5 数据类型接受 byte short int char enum(枚举)
JDK1.7 数据类型接受 byte short int char enum(枚举), String

方法、重载

/*
   方法的定义格式
      修饰符 返回值类型 方法的名字 (参数列表...){
       方法的功能主体
         循环,判断,变量,比较,运算
       return ;
    }

   修饰符:  固定写法  public static
   返回值类型:  方法在运算后,结果的数据类型
   方法名:  自定义名字,满足标识符规范, 方法名字首字母小写,后面每个单词首字母大写
   参数列表: 方法的运算过程中,是否有未知的数据, 如果有未知的数据,定义在参数列表上 (定义变量)
   return: 方法的返回, 将计算的结果返回. 结束方法
*/
public class MethodDemo{

  public static void main(String[] args){
     //调用方法, 方法执行起来
     // 在方法main中,调用方法 getArea

     int area = getArea(5,6);
     System.out.println("面积是: "+area);

  }
  /*
     要求: 计算一个长方形的面积
     定义方法解决这个要求
     分析方法定义过程:
        1. 明确方法计算后的结果的数据类型 int  定义格式对应的就是返回值类型
      2. 方法计算过程中,有没有未知的数据, 宽和长, 未知数据的数据类型 int
          未知数的变量,定义在方法的小括号内
  */
  public static int  getArea(int w, int h){
    //实现方法的功能主体
    //int area = w * h;
    return w * h;
  }
}

方法,调用中的参数传递问题
1. 方法参数是基本数据类型

  1. 方法参数是引用类型
    传递的是内存地址!

方法的重载特性 (overload)
在同一个类中,允许出现同名的方法,只要方法的参数列表不同即可,这样方法就是重载
参数列表不同: 参数的个数,数据类型,顺序
方法重载的注意事项

  1. 参数列表必须不同
  2. 重载和参数变量名无关
  3. 重载和返回值类型无关
  4. 重载和修饰符无关
    技巧: 重载看方法名和参数列表

实现引用类型、ArrayList

实现引用类型

/*
   测试,刚定义好的Phone类
   创建引用类型变量的格式

     数据类型  变量名 = new 数据类型();

  实现引用类型的步骤
    1: 导入包 , 类如果都是在同一个文件夹,不需要导入包
    2: 创建引用类型的变量
    3: 变量.类型中的功能
  文件结构:
  pack
    Phone.java
  test.java
*/
package pack;
public class test{
  public static void main(String[] args){
    // 2: 创建引用类型的变量
    Phone p = new Phone();
    //System.out.println(p);  //输出内存的地址

      //3: 变量.类型中的功能
    //变量 p.的方式,调用类中的属性
    //属性就是变量 , 赋值和获取值
    p.color = "土豪金";
    p.brand = "爱立信";
    p.size = 5.0;

    //获取属性值
    System.out.println(p.color+"  "+p.brand+"  "+p.size);
  }
}

ArrayList

/*
   ArrayList集合的使用
   也是引用数据类型
   步骤:
     1. 导入包 java.util包中
   2. 创建引用类型的变量
     数据类型< 集合存储的数据类型>  变量名 = new 数据类型 <集合存储的数据类型>  ();
     集合存储的数据类型: 要将数据存储到集合的容器中
     创建集合引用变量的时候,必须要指定好,存储的类型是什么

     ArrayList<String> array = new ArrayList<String>();

   3. 变量名.方法

   注意: 集合存储的数据,8个基本类型对应8个引用类型
   存储引用类型,不存储基本类型
*/
import java.util.ArrayList;
public class ArrayListDemo{
  public static void main(String[] args){
    //创建集合容器,指定存储的数据类型
    //存储字符串
    ArrayList<String> array = new ArrayList<String>();

    //创建集合容器,存储整数
    ArrayList<Integer> array2 = new ArrayList<Integer>();

    //创建集合容器,存储手机类型
    ArrayList<Phone> array3 = new ArrayList<Phone>();
  }
}

ArrayList 集合中的方法

add(参数) 向集合中添加元素,数据存储进去
方法中的参数类型,定义集合对象时候的类型是一致
ArrayList array = new ArrayList();
array.add(3);
get(int index) 取出集合中的元素,get方法的参数,写入索引
size() 返回集合的长度, 集合存储元素的个数
add(int 索引,存储的元素) 将元素添加到指定的索引上
set(int 索引,修改后的元素) 将指定索引的元素,进行修改
remove(int 索引) 删除指定索引上的元素
clear() 清空集合中的所有元素

对象

package cn.itcast.demo01;
/*
 *  类的方式,描述现实中的事物 小汽车
 *
 *    小汽车  属性和功能
 *      属性: 颜色  轮胎个数    变量定义
 *      功能: 跑  方法
 *
 *    属性和方法,都属于类的成员
 *
 *    属性, 成员变量
 *    方法, 成员方法
 */
public class Car {
  //定义Car类的属性

  //定义颜色属性
  String color ;
  //定义轮胎个数

  int count ;

  //定义跑的功能
  public void run(){
    System.out.println("小汽车在跑 ..."+color+"..."+count);
  }
}

package cn.itcast.demo01;
/*
 *   测试,自定义的类Car
 *   创建出Car类的变量
 *   变量,调用属性,成员变量
 *   变量,调用方法
 */
public class CarTest {

  public static void main(String[] args) {
    //创建出Car类的变量 , 创建出Car类的对象,小汽车真的有了
    Car c = new Car();
    //对象.调用类中的属性和方法
    c.color = "无色";
    c.count = 5 ;

    c.run();
  }

}

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

  1. 定义位置上的区别
    成员变量,定义在类中,方法外
    局部变量,方法内,语句内
    1. 作用域不同
      成员变量,作用范围是整个类
      局部变量,方法内,语句内
    2. 默认值不同
      成员变量,有自己的默认值
      局部变量,没有默认值,不赋值不能使用
    3. 内存位置不同
      成员变量,跟随对象进入堆内存存储
      局部变量,跟随自己的方法,进入栈内存
    4. 生命周期不同
      成员变量,跟随对象,在堆中存储,内存等待JVM清理 , 生命相对较长
      局部变量,跟随方法,方法出栈生命相对较短

提高安全问题: 让外面的类,不允许直接调用我的成员变量

新的关键字 private 私有 属于成员修饰符,不能修饰局部变量
被private修饰的成员,只能在自己的本类中被使用
对私有变量,提供公共的访问方式: 方法
private int age ;

this关键字:

  • 区分成员变量和局部变量同名情况
    • 方法中,方位成员变量,写this.

继承

extends

关键字 extends
子类是Develop, 父类是Employee
子类自动拥有父类中可以继承的属性和方法
public class Develop extends Employee{
//在子类中,可以定义方法
public void print(){
System.out.println(name);
}
}
子类中,可以直接调用父类的成员

super

在子类中,调用父类的成员,关键字 super.调用父类的成员
子类 (派生类) 继承父类 (超类,基类)
this.调用自己本类成员
super.调用的自己的父类成员
public void showNum(){
//父类的中的方法showNum已经可以号码,子类直接用
super.showNum();
System.out.println(“显示姓名”);
}

Override

继承后,子类父类中成员方法的特点
子类的对象,调用方法的时候
子类自己有,使用子类
子类自己没有,调用的是父类
重载: 方法名一样,参数列表不同,同一个类的事情
方法的重写 Override
子类中,出现了和父类一模一样的方法的时候, 子类重写父类的方法, 覆盖

子类重写父类的方法,
保证子类方法的权限大于或者等于父类方法权限
四大权限 public > protected default private

抽象类

Develop.java

package cn.itcast.demo06;
/*
 *  定义类开发工程师类
 *    EE开发工程师 :  工作
 *    Android开发工程师 : 工作
 *
 *    根据共性进行抽取,然后形成一个父类Develop
 *    定义方法,工作: 怎么工作,具体干什么呀
 *
 *    抽象类,不能实例化对象, 不能new的
 *    不能创建对象的原因:  如果真的让你new了, 对象.调用抽象方法,抽象方法没有主体,根本就不能运行
 *    子类的方法必须覆盖父类的抽象方法
 *    抽象类使用: 定义类继承抽象类,将抽象方法进行重写,创建子类的对象
 */
public abstract class Develop {
   //定义方法工作方法,但是怎么工作,说不清楚了,讲不明白
  //就不说, 方法没有主体的方法,必须使用关键字abstract修饰
  //抽象的方法,必须存在于抽象的类中,类也必须用abstract修饰
  public abstract void work();
}

JavaEE.java

package cn.itcast.demo06;
/*
 *  定义类,JavaEE的开发人员
 *  继承抽象类Develop,重写抽象的方法
 */
public class JavaEE extends Develop{
  //重写父类的抽象方法
  //去掉abstract修饰符,加上方法主体
  public void work(){
    System.out.println("JavaEE工程师在开发B/S 软件");

  }
}

Test.java

/*
 *  测试抽象类
 *    创建他的子类的对象,使用子类的对象调用方法
 */
public class Test {
  public static void main(String[] args) {
     JavaEE ee = new JavaEE();
     ee.work();
  }
}

/*
 *   抽象类,可以没有抽象方法,可以定义带有方法体的方法
 *   让子类继承后,可以直接使用
 */
public  abstract class Animal {
     public void sleep(){
       System.out.println("动物睡觉");
     }

    // private abstract void show();
     //抽象方法,需要子类重写, 如果父类方法是私有的,子类继承不了,也就没有了重写
}

接口

MyInterface.java

/*
 * 定义接口
 *   使用关键字interface  接口名字
 * 接口定义:
 *    成员方法,全抽象
 *    不能定义带有方法体的方法
 *
 * 定义抽象方法: 固定格式
 *
 *   public abstract 返回值类型  方法名字(参数列表);
 *   修饰符 public  写,或者不写,都是public
 *
 *  接口中成员变量的定义
 *    成员变量的定义,具体要求
 *
 *    要求 : 必须定义为常量
 *    固定格式:
 *      public static final 数据类型 变量名 = 值
 */
public interface MyInterface {

  //public static final int a = 1;

  //在接口中,定义抽象的方法
  public abstract void function();
}

MyInterfaceImpl.java

/*
 *   定义类, 实现接口,重写接口中的抽象方法
 *   创建实现类的对象
 *
 *   类实现接口, 可以理解为继承
 *
 *   关键字  implements
 *   class 类 implements 接口{
 *     重写接口中的抽象方法
 *   }
 *   类实现接口
 *   class MyInterfaceImpl implements MyInterface
 */
public class MyInterfaceImpl implements MyInterface{
  public void function(){
    System.out.println("实现类,重写接口抽象方法");
  }
}

Test.java

public class Test {
  public static void main(String[] args) {
    //创建接口的实现类的对象
    MyInterfaceImpl my = new MyInterfaceImpl();
    my.function();
  }
}

接口中成员的特点

  1. 成员变量的特点, 没有变量,都是常量
    固定定义格式: public static final 数据类型 变量名 = 值
    public 权限
    static 可以被类名直接.调用
    final 最终,固定住变量的值
    注意: public static final 修饰符,在接口的定义中,可以省略不写
    但是,不写不等于没有
    三个修饰符,还可以选择性书写
    1. 接口中的成员方法特点:
      public abstract 返回值类型 方法名(参数列表)
      修饰符 public abstract 可以不写,选择性书写
      但是,写不写,都有
    2. 实现类,实现接口,重写接口全部抽象方法,创建实现类对象
      实现类,重写了一部分抽象方法,实现类,还是一个抽象类

重写接口中的抽象方法, public权限是必须的

可实现多个接口

/*
 *   类C,同时去实现2个接口,接口A,B
 *   作为实现类,C,全部重写两个接口的所有抽象方法,才能建立C类的对象
 *
 *   C类,在继承一个类的同时,可以实现多个接口
 *   public interface A {
 *     public abstract void a();
 *   }
 *   public interface B {
 *      public abstract  void b();
 *   }
 *   public abstract class D {
 *      public abstract void d();
 *   }
 */

public class C extends D implements A,B{
  public void a(){

  }
  public void b(){

  }
  public void d(){

  }
}

接口多继承

package cn.itcast.demo04;
/*
 *   实现接口C,重写C接口的全部抽象方法
 *   而且接口C,继承A,B
 *   D实现类,重写A,B,C三接口全部抽象方法
 *
 *   问: Java中有多继承吗
 *    类没有多继承
 *    接口之间多继承
 *    public interface A {
 *      public abstract void a();
 *    }
 *    public interface B {
 *      public abstract void b();
 *    }
 *    public interface C extends A,B{
 *      public abstract void c();
 *    }
 */
public class D implements C{
  public void a(){}

  public void b(){}

  public void c(){}
}

多态

// 多态调用方法,方法必须运行子类的重写!!
//Java中,对象的多态性,调用程序中的方法
// 公式:  父类类型或者是接口类型   变量  = new 子类的对象();
Fu  f  = new Zi();
f.show();
//抽象类Animal,子类是Cat
Animal a = new Cat();
a.eat();
//接口Smoking,实现类Student
Smoking sk = new Student();
sk.smoking();

多态中,成员特点

成员变量:
编译的时候, 参考父类中有没有这个变量,如果有,编译成功,没有编译失败
运行的时候, 运行的是父类中的变量值
编译运行全看父类
成员方法:
编译的时候, 参考父类中有没有这个方法,如果有,编译成功,没有编译失败
运行的时候, 运行的是子类的重写方法
编译看父类,运行看子类

关键字instanceof

运算符比较运算符, 结果真假值
关键字, instanceof, 比较引用数据类型
Person p = new Student();
p = new Teacher()
关键字 instanceof 比较, 一个引用类型的变量,是不是这个类型的对象
p变量,是Student类型对象,还是Teacher类型对象
引用变量 instanceof 类名
p instanceof Student 比较,p是不是Student类型的对象,如果是,intanceof返回true


//两个子类,使用两次多态调用
Animal a1 = new Cat();
Animal a2 = new Dog();
//a1,a2调用子类父类共有方法,运行走子类的重写
a1.eat();
a2.eat();
//类型向下转型,强制转换,调用子类的特有
//防止发生异常: a1属于Cat对象,转成Cat类, a2属于Dog对象,转成Dog
//instanceof判断
if(a1 instanceof Cat){
Cat c = (Cat)a1;
c.catchMouse();
}
if(a2 instanceof Dog){
Dog d = (Dog)a2;
d.lookHome();
}

构造函数

Person.java

/*
 *  自定义的Person类.成员变量,name age
 *  要求在 new Person的同时,就指定好name,age的值
 *  实现功能,利用方法去实现, 构造方法,构造器 Constructor
 *  作用: 在new 的同时对成员变量赋值, 给对象的属性初始化赋值  new Person 对属性 name,age赋值
 *
 *  构造方法的定义格式
 *    权限  方法名(参数列表){
 *    }
 *    方法的名字,必须和类的名字完全一致
 *    构造方法不允许写返回值类型  , void 也不能写
 *
 *    构造方法在什么时候,运行呢, 在new 的时候,自动执行
 *    只运行一次,仅此而已
 *
 *    每个class必须拥有构造方法,构造方法不写也有
 *    编译的时候,javac, 会自动检查类中是否有构造方法
 *    如果有,就这样的
 *    如果没有,编译器就会自动添加一个构造方法
 *      编译器自动添加的构造方法: public Person(){}
 *    自己手写了构造方法,编译的时候,不会自动添加构造方法!
 */
public class Person {
  private String name;
  private int age;

  //定义出Person类的构造方法
  public  Person(String name,int age){
    this.name = name;
    this.age = age;
    //System.out.println("我是一个空参数构造方法");
  }

  public String getName() {
    return name;
  }
  public void setName(String name) {
    this.name = name;
  }
  public int getAge() {
    return age;
  }
  public void setAge(int age) {
    this.age = age;
  }
}

Test.java

package cn.itcast.demo01;
/*
 *  new 对象的时候,就是在调用对象的构造方法
 *   new Person(); 调用的是类中的空参数构造方法
 *   new Person("张三",20); 调用类中的有参数构造方法
 */
public class Test {
  public static void main(String[] args) {
    Person p = new Person("张三",20);
    //对象p 调用方法getName,getAge
    System.out.println(p.getName());
    System.out.println(p.getAge());
  }
}

this可以在构造方法之间进行调用
this.的方式,区分局部变量和成员变量同名情况
this在构造方法之间的调用,语法 this()

 public Person(){
    //调用了有参数的构造方法
    //参数李四,20传递给了变量name,age
    this("李四",20);
  }

构造方法,传递String,int
在创建对象的同时为成员变量赋值

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

子类中,super()的方式,调用父类的构造方法
super()调用的是父类的空参数构造
super(参数) 调用的是父类的有参数构造方法
子类的构造方法, 有一个默认添加的构造方法
注意: 子类构造方法的第一行,有一个隐式代码 super()

public Student(){
    super();
}

子类的构造方法第一行super语句,调用父类的构造方法

public class Student extends Person{
  public Student(){
    super();
  }
}

构造方法第一行,写this()还是super()
不能同时存在,任选其一,保证子类的所有构造方法调用到父类的构造方法即可
小结论: 无论如何,子类的所有构造方法,直接,间接必须调用到父类构造方法
子类的构造方法,什么都不写,默认的构造方法第一行 super();

public class Student extends Person{
  public Student(){
    //调用的是自己的构造方法
    //间接形式调用到了父类的构造方法
    this("abc");
  }
}

final、static

最终类

/*
 *  在类的定义上,加上修饰符,final
 *  类: 最终类, 不能有子类,不可以被继承
 *  但是使用方式,没有变化,创建对象,调用方法
 *
 */
public final class Fu {
  public void show(){
    System.out.println("最终类的方法");
  }
}

final方法

/*
 *  定义父类
 *  一部分方法,写成final修饰
 *  子类可以继承的,但是不能做重写
 */
public class Fu {
  public final void show(){
    System.out.println("fu类的最终方法");
  }

  public void function(){
    System.out.println("fu类的一般方法");
  }
}

static

Person.java

/*
 *   定义Person类,
 *   定义对象的特有数据,和对象的共享数据
 *   对象的特有数据(非静态修饰) 调用者只能是 new 对象
 *   对象的共享数据(静态修饰)  调用者可以是new 对象,可以是类名
 *
 *   被静态修饰的成员,可以被类名字直接调用
 */
public class Person {
  String name;
  public static void fun(){
    System.out.println("hh");
  }
  static String className;
}

Test.java

public class Test {
  public static void main(String[] args) {
    System.out.println(Person.className);
    //对象调用类的静态成员变量
    p1.className = "基础班";
    System.out.println(p2.className);
    Person.fun();//调用静态方法

  }
}

静态的注意事项
在静态中不能调用非静态为什么呢? 为什么静态不能调用非静态
生命周期静态优先于非静态存在于内存中
静态 前人 先人 非静态 后人
静态不能写this,不能写super

问题: static 修饰到底什么时候使用,应用场景
static 修饰成员变量,成员方法
成员变量加static, 根据具体事物,具体分析问题
定义事物的时候,多个事物之间是否有共性的数据!!
请你将共性的数据定义为静态的成员变量

成员方法加static, 跟着变量走
如果方法,没有调用过非静态成员,将方法定义为静态

多态静态
Fu.java

public class Fu {
  static int i = 1;

  public static void show(){
    System.out.println("父类静态方法show");
  }
}

Zi.java

public class Zi extends Fu{
  static int i = 2;
  public static void show(){
    System.out.println("子类的静态方法show");
  }
}

Test.java

/*
 *    多态调用中,编译看谁,运行看谁
 *    编译都看 = 左边的父类, 父类有编译成功,父类没有编译失败
 *    运行,静态方法, 运行父类中的静态方法
 *    运行,非静态方法,运行子类的重写方法
 *    成员变量,编译运行全是父类
 *
 *
 */
public class Test {

  public static final double PI = 3.14159265358979323846;

  public static void main(String[] args) {
    Fu f = new Zi();
//    System.out.println(f.i);
    //调用还是父类的静态方法,原因: 静态属于类,不属于对象
    //对象的多态性,静态和对象无关,父类的引用.静态方法
    f.show();
    System.out.println();
  }
}

匿名对象
Person

public class Person {
  public void eat(){
    System.out.println("人在吃饭");
  }
}

Test.java

/*
 *  有名字对象,引用类型变量,可以反复使用
 *  匿名对象,没有引用变量,只能使用一次
 *
 *  匿名对象可以当作参数传递
 *  匿名对象可以当作方法的返回值
 */

public class Test {
  public static void main(String[] args) {
    Person p = new Person();
    p.eat();

    new Person().eat();
    new Person().eat();

    method(new Person());

    Person p1 = method();
    p1.eat();
  }

  //方法返回值是Person类型
  //方法return语句,返回的是这个类的对象
  public static Person method(){
    //Person p = new Person();
    return new Person();
  }


  //调用方法method,传递Person类型对象
  public static void method(Person p){
    p.eat();
  }
}

内部类

Outer.java

/*
 *   内部类的定义
 *     将内部类,定义在了外部的成员位置
 *   类名Outer,内部类名Inner
 *
 *   成员内部类,可以使用成员修饰符,public static ....
 *   也是个类,可以继承,可以实现接口
 *
 *   调用规则: 内部类,可以使用外部类成员,包括私有
 *   外部类要使用内部类的成员,必须建立内部类对象
 */
public class Outer {
  private int a = 1;
  //外部类成员位置,定义内部类
    class Inner{
    public void inner(){
      System.out.println("内部类方法inner "+a);
    }
  }
}

Test.java

public class Test {
  public static void main(String[] args) {
    /*
     *  调用外部类中的内部类的方法inner()
     *  依靠外部类对象,找到内部类,通过内部类对象,调用内部类的方法
     *  格式:
     *    外部类名.内部类名  变量 = new 外部类对象().new 内部类对象();
     *    变量.内部类方法()
     */
    Outer.Inner in = new Outer().new Inner();
    in.inner();
  }
}

文档、jar包

集合框架

异常

Throwable
Exception 异常 感冒,阑尾炎
将异常处理掉,可以继续执行
RuntimeException
Error 非典,艾滋,癌
必须修改程序

异常对象产生和处理过程的执行流程

throw

/*
 *  异常中的关键字
 *    throw,在方法内部,抛出异常的对象
 *    throw 后面,必须写new 对象,必须是异常的对象,必须是Exception或者子类
 *
 *  方法中声明异常关键字
 *    throws 用于在方法的声明上,标明次方法,可能出现异常
 *    请调用者处理
 *    throws 后面必须写异常类的类名
 *
 *    调用了一个抛出异常的方法,调用者就必须处理
 *    不处理,编译失败
 */
public class ExceptionDemo {
  public static void main(String[] args) throws Exception {
    int[] arr = {};
    int i = getArray(arr);
    System.out.println(i);
  }
  //对数组的最后索引*2,返回
  public static int getArray(int[] arr) throws Exception {
    //对方法参数进行合法性的判断,进行判断是不是null
    if( arr == null){
      //抛出异常的形式,告诉调用者
      //关键字 throw
      throw new Exception("传递数组不存在");
    }

    //对数组进行判断,判断数组中,是不是有元素
    if(arr.length == 0){
      //抛出异常的形式,告诉调用者,数组没有元素
      throw new Exception("数组中没任何元素");
    }
    int i = arr[arr.length-1];
    return i*2;
  }
}

try…catch

/*
 *  异常的处理方式:
 *    try...catch...finally
 *    格式:
 *      try{
 *        被检测的代码
 *        可能出现异常的代码
 *      }catch(异常类名 变量){
 *         异常的处理方式
 *         循环,判断,调用方法,变量
 *      }finally{
 *         必须要执行代码
 *      }
 */
public class ExceptionDemo1 {
  public static void main(String[] args) {
    int[] arr = null;
    try{
      int i = getArray(arr);
      System.out.println(i);

    }catch(NullPointerException ex){
      System.out.println("###"+ex);

    }catch(ArrayIndexOutOfBoundsException ex){

      System.out.println("!!!!!!"+ex);
    }
    finally {
      System.out.println("必须执行");
    }//释放资源
    System.out.println("Game Over");
  }
  /*
   * 定义方法,抛出异常
   * 调用者使用try catch
   */
   public static int getArray(int[] arr)throws NullPointerException,ArrayIndexOutOfBoundsException{
     //对数组判空
     if( arr == null){
       //手动抛出异常,抛出空指针异常
       throw new NullPointerException("数组不存在");
     }
     //对数组的索引进行判断
     if( arr.length < 3){
       //手动抛出异常,抛出数组的索引越界异常
       throw new ArrayIndexOutOfBoundsException("数组没有3索引");
     }
     return arr[3]+1;
   }
}

try...catch异常处理

/*
 *  多catch写在一起
 *  细节:
 *    catch小括号中,写的是异常类的类名
 *    有没有顺序的概念,有
 *
 *    平级异常: 抛出的异常类之间,没有继承关系,没有顺序
 *      NullPointerException extends RuntimeException
 *      NoSuchElementException extends RuntimeException
 *      ArrayIndexOutOfBoundsException extends IndexOutOfBoundsException extends RuntimeException
 *
 *    上下级关系的异常
 *      NullPointerException extends RuntimeException extends Exception
 *      越高级的父类,写在下面
 */

最好用try…catch,少用throws

RuntimeException

/*
 *  异常分为编译异常和运行时期异常
 *    编译异常: 调用了抛出异常的方法,不处理编译失败  (try  throws)
 *    运行异常: 抛出的异常是RuntimeException类,或者是他的子类
 *
 *  运行异常的特点:
 *     方法内部抛出的异常是运行异常, new XXXException
 *     方法的声明上,不需要throws语句,调用者,不需要处理
 *     设计原因:
 *        运行异常,不能发生,但是如果发生了,程序人员停止程序修改源代码
 *
 *        运行异常: 一旦发生,不要处理,请你修改源代码, 运行异常一旦发生,后面的代码没有执行的意义
 */
public class RuntimeExceptionDemo {
  public static void main(String[] args) {
      double d = getArea(1);
      System.out.println(d);
  }

  /*
   *  定义方法,计算圆形的面积
   *  传递参数0,或者负数,计算的时候没有问题
   *  但是,违反了真实情况
   *  参数小于=0, 停止程序,不要在计算了
   */
  public static double getArea(double r){
    if(r <= 0)
      throw new RuntimeException("圆形不存在");
    return r*r*Math.PI;
  }


  public static void function(){
    int[] arr = {1,2,3};
    //对数组的5索引进行判断,如果5索引大于100,请将5索引上的数据/2,否则除以3
    //索引根本就没有
    if(arr[5] > 100){
      arr[5] = arr[5]/2;
    }else{
      arr[5] = arr[5]/3;
    }
  }
}

Throwable类中的方法

/*
 *  三个方法,都和异常的信息有关系
 *    String getMessage() 对异常信息的详细描述       异常了!
 *    String toString()   对异常信息的简短描述       java.lang.Exception: 异常了!
 *    void printStackTrace() 将异常信息追踪到标准的错误流  异常信息最全,JVM默认调用方法也是这个方法
 */
public class ExceptionDemo1 {
  public static void main(String[] args) {
    try{
    function();
    }catch(Exception ex){
      //System.out.println(ex.toString());
      ex.printStackTrace();
    }
  }

  public static void function() throws Exception{
    throw new Exception("异常了!");
  }
}

自定义异常

/*
 *  自定义异常
 *    继承Exception,或者继承RuntimeException
 *    构造方法中,super将异常信息,传递给父类
 */
public class FuShuException extends RuntimeException{
  public FuShuException(String s){
    super(s);
  }

  public FuShuException(){}
}
*****************************************************
public class ExceptionDemo {
  public static void main(String[] args) {

    int avg = getAvg(50,60,-70,80);
    System.out.println(avg);

  }
  /*
   * 传递成绩,计算成绩的平均数
   * 成绩没有负数,需要抛出异常,停止运算
   */
  public static int getAvg(int...source){
    int sum = 0 ;
    for(int s : source){
      if( s < 0){
        throw new FuShuException("成绩错误 "+s);
      }
      sum = sum + s;
    }
    return sum/source.length;
  }
}

/*
 *  继承后,在子类重写父类方法的时候,异常处理
 *  结论:
 *    父类的方法,如果抛出异常,子类重写后
 *      可以不抛出异常
 *      也可以抛出异常,但是,如果子类要抛,抛出的异常不能大于父类的异常
 *        大于,都指的是继承关系
 *
 *    父类的方法,没有异常抛出,子类重写后
 *       也不能抛出异常
 *       如果子类中调用了抛出异常的方法,别无选择,只能try..catch处理
 */

IO、文件操作

多线程

Thread

/*
 *  定义子类,继承Thread
 *  重写方法run
 */
public class SubThread  extends Thread{
  public void run(){
    for(int i = 0; i < 50;i++){
      System.out.println("run..."+i);
    }
  }
}
****************************************
/*
 * 创建和启动一个线程
 *   创建Thread子类对象
 *   子类对象调用方法start()
 *      让线程程序执行,JVM调用线程中的run
 */
public class ThreadDemo {
  public static void main(String[] args) {
    SubThread st = new SubThread();
    SubThread st1 = new SubThread();
    st.start();
    st1.start();
    for(int i = 0; i < 50;i++){
      System.out.println("main..."+i);
    }
  }
}

Runnable

/*
 *  实现接口方式的线程
 *    创建Thread类对象,构造方法中,传递Runnable接口实现类
 *    调用Thread类方法start()
 */
public class ThreadDemo {
  public static void main(String[] args) {
    SubRunnable sr = new SubRunnable();
    Thread t = new Thread(sr);
    t.start();
    for(int i = 0 ; i < 50; i++){
      System.out.println("main..."+i);
    }
  }
}
*********************************************
/*
 *  实现线程成功的另一个方式,接口实现
 *  实现接口Runnable,重写run方法
 */
public class SubRunnable implements Runnable{
  public void run(){
    for(int i = 0 ; i < 50; i++){
      System.out.println("run..."+i);
    }
  }
}

匿名内部类

/*
 *  使用匿名内部类,实现多线程程序
 *  前提: 继承或者接口实现
 *  new 父类或者接口(){
 *     重写抽象方法
 *  }
 */
public class ThreadDemo {
  public static void main(String[] args) {
    //继承方式  XXX extends Thread{ public void run(){}}
    new Thread(){
      public void run(){
        System.out.println("!!!");
      }
    }.start();

    //实现接口方式  XXX implements Runnable{ public void run(){}}

    Runnable r = new Runnable(){
      public void run(){
        System.out.println("###");
      }
    };
    new Thread(r).start();


    new Thread(new Runnable(){
      public void run(){
        System.out.println("@@@");
      }
    }).start();

  }
}


   转载规则


《重拾java》 刘坤胤 采用 知识共享署名 4.0 国际许可协议 进行许可。
  目录