JAVA基础DAY2

JAVA基础DAY2

Scanner对象

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

基本语法:

Scanner s = new Scanner(System.in);

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

  • next():
    1. 一定要读取到有效字符才可以结束
    2. 对输入有效字符前的空白,next()方法自动去掉
    3. 只有输入有效字符后才将其后面输入的空白作为分隔符或结束符
    4. next()不能得到带有空格的字符串
  • nextLine():
    1. 以\n为结束符,返回换行符之前的所有字符
    2. 可以获得空白

流程控制

和C++一毛一样,略

方法

Java方法是语句的集合,在一起执行一个功能

  • 方法是解决一类问题的步骤的有序组合
  • 方法包含于类或对象中
  • 方法在程序中被创建,在其他地方被引用

方法重载

函数名相同,参数不同

命令行传参

有时候希望运行一个程序时再传递给它消息,要靠命令行参数给main()实现。

package Scanner;

public class Demo01 {
    public static void main(String[] args) {
        for (int i = 0; i < args.length; i++){
            System.out.println("args["+i+"]"+args[i]);
        }
    }
}

因为包含了package Scanner,所以必须在Scanner的上一层目录执行该程序

在这里插入图片描述

可变参数

JDK1.5之后,Java支持传递同类型的可变参数给一个方法

在方法声明中,在指定参数类型后加一个省略号(…)

一个方法中只能指定一个可变参数,它必须是方法的最后一个参数,任何普通的参数必须在它之前声明。

public class Demo01 {
    public static void main(String[] args) {
        Demo01 demo01 = new Demo01();
        demo01.printMax(1,2,3);
        //demo01.printMax(new double[]{1,2,3}) also correct
    }
    public void printMax(double... nums)
    {
        if(nums.length==0)
        {
            System.out.println("no nums!");
            return;
        }
        double max=-1e9;
        for (double num : nums)
        {
            if(num>max)
                max = num;
        }
        System.out.println("The biggest num in nums is :"+max);
    }
}

数组

声明方法

// 1.声明
int[] arr;	//首选声明方法
int arr[];	//可以,但是不要
// 2.创建一个数组
arr = new int[10];

数组变量是引用类型,数组也可以看成是对象,数组中每个元素相当于该对象的成员变量,数组本身就是对象,Java的对象在堆中,因此数组无论保存原始类型还是其他对象类型,数组对象本身在堆中

多维数组

int[][] arr = {{1,2},{2,3}};
int[][] arr = new int[2][2];

Arrays类

  • 数组的工具类java.util.Arrays
  • Arrays类中的方法都是static修饰的静态方法,在使用的时候可以直接使用类名进行调用,而"不用"使用对象来调用(注意是“不用”而非“不能”)
  • 常用方法:
    • 赋值:fill()
    • 排序:sort(),升序
    • 比较:equals()
    • 查找元素:binarySearch()

OOP

继承

extends的意思是"扩展",子类是父类的扩展

JAVA中只有单继承,无多继承!!!

Object类

通过ctrl+H看到类的继承关系

在这里插入图片描述

发现所有类都继承一Object类,该类提供了一些基础方法。

Super

调用父类的值和方法,与this对应

private属性的值和方法super无法访问

super():父类构造器,必须放在子类构造器的第一行

super和this不能同时调用构造方法

方法重写

  • 静态方法

重写和静态方法没有关系,只和非静态方法有关系

public class A extends B{
    public static void test()
    {
        System.out.println("A=>test()");
    }
}

public class B{
    public static void test()
    {
        System.out.println("B=>test()");
    }
}

//方法的调用只和定义的数据类型有关
A a = new A();
a.test();//A=>test

//父类引用指向子类
B b = new A();
b.test();//B=>test
  • 非静态方法
public class A extends B{
    @Override //注解:有功能的注释!
    public void test()
    {
        System.out.println("A=>test()");
    }
}

public class B{
    public void test()
    {
        System.out.println("B=>test()");
    }
}

A a = new A();
a.test();//A=>test

//子类重写了父类的方法
B b = new A();
b.test();//A=>test
  • 注意点
    • 方法名、参数列表必须相同
    • 修饰符:范围可以扩大,不能缩小 public>protected>default>private
    • 抛出的异常:范围可以被缩小不能扩大

使用Alt+Insert:override也可使用快捷键进行重载

多态

同一方法根据发送对象的不同而采取多种不同的行为方式

一个对象的实际类型是确定的,但可以指向对象的引用类型有很多

/*
say() from both Student and Person
eat() only from Student
*/

// Student 能调用的方法是自己的或继承父类的
Student s1 = new Student();
// Person 可以指向子类,但不能调用Student独有的
Person s2 = new Student();
Object s3 = new Student();

s2.say();//equals ((Student) s2).say()=>Student say!
s1.eat();//correct
s2.eat();//wrong
  • 注意事项
    • 属性没有多态
    • 多态源自继承,方法需要重写
    • 父类引用指向子类对象,如果调用的方法在子类重载了则调用子类的方法。
    • 动态编译,程序在运行时才知道执行哪个方法
    • 不能多态的:
      • static:属于类,不属于实例
      • final:常量
      • private方法

instanceof

boolean result = obj instanceof Class

​ 其中 obj 为一个对象,Class 表示一个类或者一个接口,当 obj 为 Class 的对象,或者是其直接或间接子类,或者是其接口的实现类,结果result 都返回 true,否则返回false。

注意:编译器会检查 obj 是否能转换成右边的class类型,如果不能转换则直接报错,如果不能确定类型,则通过编译,具体看运行时定。

  1. obj必须是引用类型,不能是基本类型
int i;
i instanceof Interger;//编译不通过
  1. obj为null

null算作基本类型和引用类型之外的一种类型,null是可以成为任意引用类型的特殊符号,如果obj为null返回false

null instanceof Object;//false
  1. obj为class的实例对象
Interger i = new Interger(1);
i instanceof Interger;//true
  1. obj为class类的直接或间接子类

true or false与引用是什么类型无关,而是与对象是什么类型有关

public class Man extends Person{}

Person p1 = new Person();
Person p2 = new Man();
Man m1 = new Man();
System.out.println(p1 instanceof Man);//false
System.out.println(p2 instanceof Man);//true
System.out.println(m1 instanceof Man);//true
  1. 编译不通过

编译器会检查 obj 是否能转换成右边的class类型,如果不能转换则直接报错,如果不能确定类型,则通过编译,具体看运行时定。

Person p1 = new Person();
 
System.out.println(p1 instanceof String);//编译报错
System.out.println(p1 instanceof List);//false
System.out.println(p1 instanceof List<Person>);//编译报错

按照我们上面的说法,这里就存在问题了,Person 的对象 p1 很明显不能转换为 String 对象,那么自然 Person 的对象 p1 instanceof String 不能通过编译,但为什么 p1 instanceof List 却能通过编译呢?而 instanceof List 又不能通过编译了?

instanceof伪代码:

boolean result;
if (obj == null) {
  result = false;
} else {
  try {
      T temp = (T) obj; // checkcast
      result = true;
  } catch (ClassCastException e) {
      result = false;
  }
}

简单来说就是:**如果 obj 不为 null 并且 (T) obj 不抛 ClassCastException 异常则该表达式值为 true ,否则值为 false 。**因为(String)p1不能通过编译,而(List)p1可以,具体为什么之后再讨论。

static

静态变量被类中所有实例共享——在内存区里面只有一份,存储在专门的静态区中,可以直接通过类名访问,在类中调用静态属性或方法也不需要实例化对象就可以使用

静态导入包
//比如说只想导入Math.random这一个方法
//static不能少!
import static java.lang.Math.random;

random()//可以直接用,而非Math.random()

抽象类

//抽象类
public abstract class Action{
    
    //抽象方法,只有方法名,没有实现
    public abstract void doSomething();
    //普通方法
    public void doSpecificThing()
    {
        //实现
    }
}

//子类必须实现所有的抽象方法,不然子类仍然是抽象方法!
public class A extends Action{
    @Override
    public abstract void doSomething()
    {
        //方法实现
    }
}

抽象类不能实例化(new)

存在意义?提高代码开发效率,但是用的比较少,因为只能单继承,多用接口

接口

  • 普通类:只有具体实现
  • 抽象类:具体实现和规范(抽象方法)都有
  • 接口:只有规范

关键字:interface

public interface TimeService {
    void timer();
}
//每个接口都要有实现类
public interface UserService {
    //属性都是public static final
    int age = 99;
    //方法都是public abstract
    void run(String name);
}

//类 可以实现接口,并且可以实现多个接口以实现多继承
public class UserServiceImp implements TimeService,UserService{
    @Override
    public void timer() {
    }
    @Override
    public void run(String name) {
    }
}

作用:

  1. 定义一些方法的架构,让不同的人实现
  2. 接口不能被实例化,没有构造方法
  3. implements可以实现多个接口
  4. 必须要重写接口中的方法

异常

  1. 检查性异常

    最具代表的检查性异常是用户错误或问题引起的异常,这是程序员无法预见的。例如要打开一个不存在的文件,一个异常就发生了,这些异常在编译时不能被简单地忽略

  2. 运行时异常

    最可能被避免的异常,可以在编译时被忽略。

  3. 错误ERROR

    不是异常,是脱离程序员控制的问题,经常在代码中被忽略。例如,栈溢出,在编译中检查不到。

Error和Exception的区别:Error通常是灾难性的致命的错误,程序无法控制和处理的,当出现这些异常,JVM选择终止线程;Exception通常情况下是可以被程序处理的,并且在程序中应该尽可能的去处理这些异常。

异常处理机制

  • 抛出异常
  • 捕获异常

快捷键ctrl Alt + T

// 可以用catch多次捕获,但是必须越细节异常在最上面
// 不过有没有捕获异常,都执行finally,经常用于执行一些IO或资源的关闭工作
try{//监控区域
    System.out.println(a/b);
}catch (ArithmeticException e){//想要捕获的异常
    System.out.println("程序出现异常,变量b不能为0");
}catch(Throwable e){
    System.out.println("Throwable");
}finally{
    System.out.println("finally");
}

//主动抛出异常,一般用在方法实现内部
try{
    if (b==0)
    	throw new ArithmeticException();
}

//throws用在方法声明时
public void test(int a) throws ArithmeticException{
   //表示这个方法可能会抛出这个异常,提醒调用者要进行处理 
}

throws:用来声明一个方法可能产生的所有异常,不做任何处理而是将异常往上传,谁调用我我就抛给谁。

用在方法声明后面,跟的是异常类名
可以跟多个异常类名,用逗号隔开
表示抛出异常,由该方法的调用者来处理
throws表示出现异常的一种可能性,并不一定会发生这些异常

throw:则是用来抛出一个具体的异常类型。

用在方法体内,跟的是异常对象名
只能抛出一个异常对象名
表示抛出异常,由方法体内的语句处理
throw则是抛出了异常,执行throw则一定抛出了某种异常

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值