- next() 与 nextLine() 区别next():
- 一定要读取到有效字符后才可以结束输入。
- 对输入有效字符之前遇到的空白,next() 方法会自动将其去掉。
- 只有输入有效字符后才将其后面输入的空白作为分隔符或者结束符。
- next() 不能得到带有空格的字符串。
- nextLine():
- 以Enter为结束符,也就是说 nextLine()方法返回的是输入回车之前的所有字符。
- 可以获得空白。
- 通过 Scanner 类的 next()与 nextLine() 方法获取输入的字符串,在读取前我们一般需要 使用 hasNext与 hasNextLine判断是否还有输入的数据:
- hasNext() 与 hasNextLine() 区别hasNext():
- 1、输出为布尔值。
- 2、判断输入的缓存中是否有效字符,遇到空格结束。
- 3、如果只输入空格,不会匹配,返回false。
- hasNextLine():
- 1、以Enter为结束符,判断此行有没有输入,空白输入也会返回true。
- 通过 Scanner 类的 next() 与 nextLine() 方法获取输入的字符串,在读取前我们一般需要 使用 hasNext 与 hasNextLine 判断是否还有输入的数据:
- 使用中的正确搭配
hasNext() —> next()
hasNextLine()——> nextLine() 测试交叉搭配方式如果hasNext()和nextLine() 搭配使用:
Scanner sc = new Scanner(System.in);
while (sc.hasNext()) {
System.out.println(sc.nextLine());
}
效果如下:
- 如果输入一个空格,hasNext()检测空格到空格,不会匹配(hasNextLine()会匹配),后面接着输入一个有效字符串,就会连着前面输入的空格一起输出。
- 最有一个输入a b c,输入了abc,那是因为我再控制台输入的时候先输入了abc,然后再改成了a b c,然后就输出了abc,多次测试之后,结论为在你输入内容的时候之后,再在内容中插入空格,输出结果中不会含有空格。
如果hasNext()和nextLine() 搭配使用:
Scanner sc = new Scanner(System.in);
while (sc.hasNextLine()) {
System.out.println(sc.next());
}
效果如下:
如果输出一行的字符串用空格隔开,那么每一次next()只会读取空格之前的一个字符。
比如上面的输入:a b c,在next()读取到a的时候遇到空格,那就只读取a,而缓存中还剩下b c,继续循环,hasNextLine()返回true,读取缓存中的内容,直到读完。System.out.print(i+” * “+j+” = “+s+” “);
循环嵌套:
一维数组内存分配:
数组访问:
Arrays.sort() 方法:
(默认为从小到大排序)
判断输入的字符串是否是回文:
valueOf方法:
- 由 基本数据型态转换成 String
String 类别中已经提供了将基本数据型态转换成 String 的 static 方法
也就是 String.valueOf() 这个参数多载的方法
有下列几种
String.valueOf(boolean b) : 将 boolean 变量 b 转换成字符串
String.valueOf(char c) : 将 char 变量 c 转换成字符串
String.valueOf(char[] data) : 将 char 数组 data 转换成字符串
String.valueOf(char[] data, int offset, int count) :
将 char 数组 data 中 由 data[offset] 开始取 count 个元素 转换成字符串
String.valueOf(double d) : 将 double 变量 d 转换成字符串
String.valueOf(float f) : 将 float 变量 f 转换成字符串
String.valueOf(int i) : 将 int 变量 i 转换成字符串
String.valueOf(long l) : 将 long 变量 l 转换成字符串
String.valueOf(Object obj) : 将 obj 对象转换成 字符串, 等于 obj.toString()
用法如:
int i = 10;
String str = String.valueOf(i);
这时候 str 就会是 “10”
2. 由 String 转换成 数字的基本数据型态
要将 String 转换成基本数据型态转
大多需要使用基本数据型态的包装类别
比如说 String 转换成 byte
可以使用 Byte.parseByte(String s)
这一类的方法如果无法将 s 分析 则会丢出 NumberFormatException
byte :
Byte.parseByte(String s) : 将 s 转换成 byte
Byte.parseByte(String s, int radix) : 以 radix 为基底 将 s 转换为 byte
比如说 Byte.parseByte(“11”, 16) 会得到 17
double :
Double.parseDouble(String s) : 将 s 转换成 double
float :
Double.parseFloat(String s) : 将 s 转换成 float
int :
Integer.parseInt(String s) : 将 s 转换成 int
long :
Long.parseLong(String s)1. 由 基本数据型态转换成 String
String 类别中已经提供了将基本数据型态转换成 String 的 static 方法
也就是 String.valueOf() 这个参数多载的方法equals()的理解:
equals()比较的是同一个类型的两个不同对象里的属性们是否都相等,相等返回true,否则返回false。
API中某些常用的类(如String、Date、File、包装类等)都已经重写了Object类中的equals()方法,所以可以直接调用,而自己定义的类没有重写,需要的话就自己重写equals(),快捷键(在Eclipce中Alt Shift S)按一下就写好了。
面试题:==和equals()的区别
1、= =:是运算符。 既可以比较基本类型也可以比较引用类型。对于基本类型就是比较值,而引用类型就是比较内存地址。并且必须保证符号左右两边的变量类型一致,即都是比较基本类型,或者都是比较引用类型。
2、equals():是java.lang.Object类里面的方法。只能适用于引用数据类型。如果类的该方法没有被重写过默认也是= =
例子
private String name;
private int age;
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;
}
public Customer() {
super();
}
public Customer(String name, int age) {
super();
this.name = name;
this.age = age;
}
//自动生成的equals()
@Override
public boolean equals(Object obj) { // 用传进来的对象做比较
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Customer other = (Customer) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
@Override
public String toString() {
return "Customer [name=" + name + ", age=" + age + "]";
}
}
public static void main(String[] args) {
Customer cust1 = new Customer("Tom",21);
Customer cust2 = new Customer("Tom",21);
System.out.println(cust1.equals(cust2)); //true(因为没有重写就是false,因为调用的是Object父类的equals,这比较的是 == ,是地址值,重写了equals方法才是对比里面的具体内容)。
}
原始的ArrayTool.java类:
1.package com.vnb.javabase;
/**
*
* Description:数组工具类
* @author li.mf
* @date 2018年8月15日
*
*/
public class ArrayTool {
/**
* 获取数组最大值
* @param arr
* @return
*/
public int getMax(int[] arr){
int max = 0;
for (int i = 1; i < arr.length; i++) {
if(arr[max]<arr[i]){
max = i;
}
}
return arr[max];
}
/**
* 获取数组最小值
* @param arr
* @return
*/
public int getMin(int[] arr){
int min = 0;
for (int i = 1; i < arr.length; i++) {
if(arr[min]>arr[i]){
min = i;
}
}
return arr[min];
}
/**
* 选择排序
* @param arr
*/
public void selectSort(int[] arr){
for (int i = 0; i < arr.length-1; i++) {
for (int j = i+1; j < arr.length; j++) {
if(arr[i]>arr[j]){
swap(arr,i,j);
}
}
}
}
/**
* 冒泡排序
* @param arr
*/
public void bubbleSort(int[] arr){
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr.length-i-1; j++) {
if(arr[j]>arr[j+1]){
swap(arr,j,j+1);
}
}
}
}
public void swap(int[] arr,int a,int b){
int temp = arr[a];
arr[a] = arr[b];
arr[b] = temp;
}
public void printArray(int[] arr){
System.out.print("{");
for (int i = 0; i < arr.length; i++) {
if(i!=arr.length-1){
System.out.print(arr[i]+",");
}else{
System.out.print(arr[i]+"}");
}
}
}
}
面向对象三大特性:
面向对象编程是利用 类和对象编程的一种思想。万物可归类,类是对于世界事物的高度抽象 ,不同的事物之间有不同的关系 ,一个类自身与外界的封装关系,一个父类和子类的继承关系, 一个类和多个类的多态关系。万物皆对象,对象是具体的世界事物,面向对象的三大特征封装,继承,多态,封装,封装说明一个类行为和属性与其他类的关系,低耦合,高内聚;继承是父类和子类的关系,多态说的是类与类的关系。
1. 封装
- 什么是封装
把客观事物封装成抽象的类,并且把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。也 就 是 说抽象数据类型对数据信息以及对数据的操作进行打包,将其变成一个不可分割 的实体,在这个实体内部,我们对数据进行隐藏和保密,只留下一些接口供外部调用。
简单的说,一个类就是一个封装了数据以及操作这些数据的代码的逻辑实体。在一个对象内部,某些代码或某些数据可以是私有的,不能被外界访问。通过这种方式,对象对内部数据提供了不同级别的保护,以防止程序中无关的部分意外的改变或错误的使用了对象的私有部分。
封装隐藏了类的内部实现机制,可以在不影响使用的情况下改变类的内部结构,同时也保护了数据。对外界而已它的内部细节是隐藏的,暴露给外界的只是它的访问方法。
就好比一个烤面包机,我们把面包(数据)放进去,按下开关,过了一会,它就会自动弹出烤好的面包(处理后的信息),而这个过程是怎么烤的(对数据的操作),我们是不需要知道的,
• 1
- 为什么需要封装
隐藏一个类中不需要对外提供的实现细节;
属性的封装:使用者只能通过事先定制好的方法来访问数据,可以方便地加入逻辑控制,限制对属性的 不合理操作;
方法的封装:使用者按照既定的方式调用方法,不必关心方法的内部实现,便于使用; 便于修改,增强 代码的可维护性;
-如何封装
利用权限修饰符来描述方法体或属性。private修饰的属性或方法为该类所特有,在任何其他类中都不能直接访问;default修饰的属性或方法具有包访问特性,同一个包中的其他类可以访问;protected修饰的属性或方法在同一个中的其他类可以访问,同时对于不在同一个包中的子类中也可以访问;public修饰的属性或方法外部类中都可以直接访问。
封装类似于黑箱操作,其设计要求是低耦合,高内聚。一个具体复杂的对象有很多的属性和方法,有些需要公开,有些不需要公开,就好比一个具体的人的信息,有些是public,有些是private,而有些是protecred,别人问到的时候对于怎么样的信息都有不同的态度。根据与这个人的关系来回答问题,封装的结果是输出结果,不问过程,其中,public是可以被任何变量访问的,private是该类私有的,protected类是受保护的,可以被该类所述的包内的所有的其他类访问,其子类也可以访问。
比如我们将一个房子看做是一个对象,里面的漂亮的装饰,如沙发、电视剧、空调、茶桌等等都是该房子的私有属性,但是如果我们没有那些墙遮挡,是不是别人就会一览无余呢?没有一点儿隐私!就是存在那个遮挡的墙,我们既能够有自己的隐私而且我们可以随意的更改里面的摆设而不会影响到其他的。但是如果没有门窗,一个包裹的严严实实的黑盒子,又有什么存在的意义呢?所以通过门窗别人也能够看到里面的风景。所以说门窗就是房子对象留给外界访问的接口。
2.继承
什么是继承
继承是从已有的类中派生出新的类,新的类能吸收已有类的数据属性和行为,并能扩展新的能力。
在本职上是特殊——一般的关系,即常说的is-a关系。子类继承父类,表明子类是一种特殊的父类,并且具有父类所不具有的一些属性或方法。从多种实现类中抽象出一个基类,使其具备多种实现类的共同特性 ,当实现类用extends关键字继承了基类(父类)后,实现类就具备了这些相同的属性。
继承的类叫做子类(派生类或者超类),被继承的类叫做父类(或者基类)。
比如从猫类、狗类、虎类中可以抽象出一个动物类,具有和猫、狗、虎类的共同特性(吃、跑、叫等)。如何实现继承: Java通过extends关键字来实现继承,父类中通过private定义的变量和方法不会被继承,不能在子类中直接操作父类通过private定义的变量以及方法。继承的优点: 继承避免了对一般类和特殊类之间共同特征进行的重复描述,通过继承可以清晰地表达每一项共同特征所适应的概念范围——在一般类中定义的属性和操作适应于这个类本身以及它以下的每一层特殊类的全部对象。运用继承原则使得系统模型比较简练也比较清晰。- 继承有哪些原则成员变量的继承原则 具体的原则如下:
- [u ] 能够继承父类的public和protected成员变量;不能够继承父类的private成员变量;
- [u ] 对于父类的包访问权限成员变量,如果子类和父类在同一个包下,则子类能够继承;否则,子类不能够继承;
- [y ] 对于子类可以继承的父类成员变量,如果在子类中出现了同名称的成员变量,则会发生隐藏现象,即子类的成员变量会屏蔽掉父类的同名成员变量。如果要在子类中访问父类中同名成员变量,需要使用super关键字来进行引用。
1.方法的重写
子类如果对继承的父类的方法不满意(不适合),可以自己编写继承的方法,这种方式就称为方法的重写.通过重写父类的方法,可以用自身的行为代替父类的行为。当调用方法时会优先调用子类的方法。重写要注意: a、返回值类型 b、方法名 c、参数类型及个数
都要与父类继承的方法相同,才叫方法的重写。
重载和重写的区别:
方法重载:在同一个类中处理不同数据的多个相同方法名的多态手段。
方法重写:相对继承而言,子类中对父类已经存在的方法进行区别化的修改
2. 继承初始化顺序
父类的构造器调用以及初始化过程一定在子类的前面
1、初始化父类再初始化子类
2、先执行初始化对象中属性,再执行构造方法中的初始化。
基于上面两点,我们就知道实例化一个子类,java程序的执行顺序是:
父类对象属性初始化——>父类对象构造方法——>子类对象属性初始化—>子类对象构造方法
下面有个形象的图:
继承实例:/**
1. 我是父类super
2. 我是子类sub
3. 先打印的是父类里面的在打印的子类里面
4. 从这个可以看出是先调用父类的构造方法创建父类对象再来调用子类里面的构造方法
*/
class Super{
public Super(){
System.out.println("我是父类super");
}
}
class Sub extends Super{
public Sub(){
System.out.println("我是子类sub");
}
}
public class InstanceDemo {
public static void main(String[] args) {
new Sub();
}
}
3.多态
Java 面向对象编程之多态
相比于封装和继承,Java多态是三大特性中比较难的一个,封装和继承最后归结于多态, 多态指的是类和类的关系,两个类由继承关系,存在有方法的重写,故而可以在调用时有父类引用指向子类对象。自己对于多态的理解还不够深刻,故而转载了一篇关于多态比较好的文章。 ``` public class main {/**
@param args */ public static void main(String[] args) { //分别将animal实例化成三种动物,
Animal an = new Dog(); an.cry();//根据每种动物自身的方法,自动选择内容 an = new Cat(); an.cry(); an = new UnknowAnimal(); an.cry(); } } //基本类,包含一个基本方法 class Animal{ public void cry(){ System.out.println(“我不知道自己是什么动物。”); } } //声明子类,继承基本类,但有自己的方法 //实例化后优先使用自身的方法。 class Dog extends Animal{ public void cry(){ System.out.println(“这是一条狗。”); } } e class Cat extends Animal{ public void cry(){ System.out.println(“这是一只猫。”); } } //这个子类自身没定义方法,实例化后会使用从父类继承来的方法 class UnknowAnimal extends Animal{
构造方法:
1.封装:
1.先建立一个Student类
2.后建立一个StudentDemo类(该文件为运行出结果)
2.继承:
静态static:
实例:
构造一个方法,求一个一维数组的反向反序:
静态方法只能访问静态成员(成员变量和方法),非静态方法既可以访问静态成员也可以访问非静态成员
主函数中的静态
主函数是静态的:主函数是一个特殊的函数,作为程序的入口,可以直接被JVM调用。
主函数的定义:
public:代表着该函数访问权限是最大的
static:代表主函数随着类的加载就已经存在了
void:代表主函数没有具体的返回值返给虚拟机JVM
main:不是关键字,但是是一个特殊的单词,可以被JVM识别,且是主函数特有的。
String[] args: 函数的参数,参数类型是一个数组,该数组中的元素是字符串,字符串类型的数组。
主函数是固定格式的:JVM识别
public static void main(int x){}也可以写(主函数被重载),但是JVM会优先从public static void main(String[] args){}开始执行。JVM在调用主函数时,传入的是 new String[0],作用:可以往参数里传入数据,在主函数里就可以拿到参数。
传递参数给主函数并由主函数获取:
使用命令传:
java 类名 参数
this.name不可用,this代表对象,而静态方法优先于对象创建,在执行静态方法show()时,对象Person还未创建,所以此时this 还未初始化过,所以不可用。