目录
大学时候学的C#,感觉4年过来,好像学的内容什么都明白,又好像什么都不明白,感觉很迷茫。
然后被周围学java的洗脑了,我就打算试着学学java,看看能不能提起来学习兴趣,于是我找了个老师,他给我发了些java基础的学习视频,于是我就这样走上了java学(bu)习(gui)之路(2018年8月15号开始 )
下面总结下从0开始学java的每日心得:
(初学乍道,下方内容如有错误,请您指出!这可能对我有非常大的帮助!万分感谢!!)
2018年8月15日
学习的第一天,大致了解了java的发展史,然后按照教程安装了JDK,配置了java的环境,下载了Notepad++,并使用Notepad++编写了第一个HelloWorld (javac 文件名.java 编译,然后java 类名(无后缀)运行),以及8种基本数据类型:byte,short,int,long,float,double,char,boolean 以及引用类型String等基本知识。
2018年8月16日
学习基本数据类型的转换,以及算术运算符的使用,比较运算符的使用,三元运算符的使用等,以及方法的入门概念,如方法public static void fangfa (){System.out.printfln("方法调用");},在main方法中单独调用fangfa();等。
2018年8月17日
学习if,if-else,switch,while,do-while,for等语句的基本使用方法。
(以及break与countinue的使用)
2018年8月18日
安装IDEA(IntelliJ),学会基本的IDEA使用方法,了解部分常用快捷键,如ALT+4,CTRL+SHIFT+F10(运行)等,并简单学习如何用正确格式编写方法,以及学习“调用方法”的3种方法(单独调用,打印调用,赋值调用),学习最基本的方法重载。
2018年8月19日
学习数组的使用,以及如何访问数组元素,如遍历数组等,熟悉java的内存划分(栈-局部变量与方法,堆-new,方法体-class,本地方法栈,寄存器),此外,也学习了如何获取数组长度 数组名.length,以及练习如何求数组中最大值(主要):
public class other {
public static void main(String[] args) {
int[] array = {1, 2, 3, 4, 5};
int max = array[0];
for (int i = 1; i < array.length; i++) {
if (max < array[i]) {
max = array[i];
}
System.out.println(max);
}
}
}
还有一个是练习如何反转数组,如[1,2,3,4]改变为[4,3,2,1]
int[] array={1,2,3,4};
for(int min=0,max=array.length-1;min<max;min++,max--)
{
int temp=array[min];
array[min]=array[max];
array[max]=temp;
}
// 再一次遍历数组输出
for(int i=0;i<array.length;i++)
{
System.out.println(array[i]);
}
2018年8月20日
首先举个例子(面向过程与面向对象)
了解面向过程(每一个细节都要亲力亲为)与面向对象,首先用面向过程输出一个数组“[1,2,3,4,5]”
int[] array = {1, 2, 3, 4, 5};
//输出[1,2,3,4,5] 先用面向过程
System.out.print("[");
for (int i = 0; i < array.length; i++) {
if (i == array.length - 1) {
System.out.print(array[i] + "]");
} else {
System.out.print(array[i] + ",");
}
}
然后用面向对象再一次输出数组“[1,2,3,4,5]”
PS:
int[] array = {1, 2, 3, 4, 5};
/*
这里用到Arrays.toString()
节省了遍历数组的循环步骤,
而一步输出(当然,调用函数的内部进行了处理)。
*/
System.out.println(Arrays.toString(array));
了解最基本的类(包含成员变量,与成员方法,其实也就是属性和方法)的使用。
其中成员变量定义的变量,是在类中定义(在方法外面定义),成员方法不写“static”关键字(与返回值 参数无关)
通常情况下,一个类不能直接使用,需要根据类创建一个对象才能使用。
如何创造对象?
1、导包:指出需要使用的类,在什么位置。
格式:import 包名称.类名称;
对于 和当前类 属于同一个包(package)的情况,可以省略包不写。
2、创建
格式:类名 对象名 = new 类名();
如:Student stu=new Student();
3、使用
a.使用成员变量:对象名.成员变量名
b.使用成员方法:对象名.成员方法名(参与);
(也就是想用谁,就用 对象名字 点 谁)
如:建立一个Student类
package cn.itcast.day6.demo1;
public class Student {
String name;
int age;
public static void main(String[] args) {
}
public void eat(){
System.out.println("吃饭饭!");
}
public void sleap(){
System.out.println("睡觉!");
}
public void study(){
System.out.println("学习");
}
public void sum(int a,int b){
int c=a+b;
System.out.println(c);
}
}
然后在新建一个对象(Student stu),使用Student类,如:
package cn.itcast.day6.demo1;
//因为与类是在同一个包中,这里就不导入包了
public class demo2 {
public static void main(String[] args) {
Student stu= new Student();
stu.name="aaa";//因为Student中的name成员变量没有赋值。
System.out.println(stu.name);
stu.eat();//Student类中的eat成员方法
stu.sum(1,2);//Student类中的sum成员方法
}
}
随堂练习:创建一个phone类与一个phones(phone p)对象。
phone类:
package cn.itcast.day6.demo1;
public class phone {
String pinpai; //品牌
double price; //价格
String color; //颜色
//给某人打电话
public void dadianhua(String who){
System.out.println("我可以给"+who+"打电话");
}
//给某人发短信
public void sendMessage(String who){
System.out.println("我可以给"+who+"发短信");
}
// 群发短信
public void allSendMessage(){
System.out.println("我可以群发短信");
}
}
phones(phone p)对象
package cn.itcast.day6.demo1;
public class phones {
public static void main(String[] args) {
phone p=new phone();
p.color="红色";
p.pinpai="小明手机";
p.price=100;
//输出phone类中的成员变量
System.out.println(p.color);
System.out.println(p.pinpai);
System.out.println(p.price);
//输出phone类中的成员方法
p.allSendMessage();
p.dadianhua("小明");
p.sendMessage("小红");
}
}
phohe类和phones对象(phone one)的内存图:
以下是2个对象(phone one / phone two) 使用同一个类的 内存图
还有一种情况是 phone two=one;的内存图(也就是2个对象名称 指向 同一个类)
了解private关键字的基本使用方法,使得类外无法直接访问,但可使用get set方法访问private。
如:
public class person {
String name;
private int age;
public void show() {
System.out.println("我叫" + name);
System.out.println("我今年" + age + "岁");
}
public void setAge(int num) {
if (num > 0 && num < 100) {
age = num;
} else {
System.out.println("数据错误!");
}
}
public int getAge() {
return age;
}
}
此外有一特例,boolean类型是 setXX isXX。
了解this关键字用法,用于访问本类中的成员变量。
了解构造方法(用途是创造对象,且构造方法可以重载),格式是:public 类名(ps:大小写也需完全一样) (参数类型 参数名){方法体},且构造方法一定不要写返回值类型(也就是不要写return返回具体数值,说白了也就是不能产生返回值!),连void也不要写!
如:
public class student {
public student(){
System.out.println("构造方法执行了!");
}
}
但一旦写了至少1个构造方法,编译器就不会自动生成构造方法。
如构造方法(加set get是因为后续可能要对相应数值进行改变):
public class student {
private String name;
private int age;
public student() {
System.out.println("无参构造方法执行了!");
}
public student(String name, int age) {
System.out.println("有参构造方法执行了!");
this.name = name;
this.age = age;
System.out.println("我是" + name + "我今年" + age);
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setAge(int age) {
this.age = age;
}
public int getAge() {
return age;
}
}
然后使用:
public class demo1 {
public static void main(String[] args) {
student stu1=new student();
student stu2=new student("名字",22);
System.out.println("11111111");
stu2.setAge(12);
stu2.setName("啊啊");
System.out.println(stu2.getAge());
System.out.println(stu2.getName());
}
}
一个标准的类,通常由4部分组成:
1、所有的成员变量都要使用private关键字进行私有化修饰
2、为每一个成员变量编写一对set get方法
3、编写一个无参构造方法
4、编写一个全参构造方法
(这样标准的类也就是 Java Bean)
综合上述4方面,随堂练习如:
其中,只需要手动编写2行代码(成员变量),其余set get方法,无参,有参方法均使用Code→Generate(ALT+INSERT)自动补全,其中无参和有参构造方法使用Constructor,选择对应参与或不选即可生成。
private String name;
private int age;
//下方为自动补全后的代码
public class Student {
private String name;
private int age;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
然后创建对象使用上述Student类:
public class demo01 {
public static void main(String[] args) {
Student stu1=new Student(); //生成对象stu1
stu1.setName("迪丽热巴"); //使用set方法对成员变量name赋值
stu1.setAge(21);//使用set方法对成员变量agt赋值
System.out.println("姓名是:"+stu1.getName()); //通过get方法显示对应内容
System.out.println("年龄是:"+stu1.getAge());//通过get方法显示对应内容
System.out.println("================"); //分割线
Student stu2=new Student("小明",18); //生成对象stu2,并加参数
System.out.println("姓名是:"+stu2.getName()+",年龄是:"+stu2.getAge()); // 将name与age的值显示
stu2.setAge(20); //通过set方法修改age的值
stu2.setName("小明改名字了!");//通过set方法修改name的值
System.out.println("姓名是:"+stu2.getName()+"年龄是:"+stu2.getAge()); //显示
}
}
2018年8月21日
今天先大致了解API(应用程序编程接口),也就是包含了很多的类与方法。
了解Scanner方法使用(如键盘输出,当new了Scanner方法后,需要在括号内填写System.in)。
随堂练习,键盘输出2个数字,求和。
package cn.itcast.day07.demo;
import java.util.Scanner; //导包格式 import.包名.类名
public class demo1scanner {
public static void main(String[] args) {
Scanner scan=new Scanner(System.in); //生成Scanner对象
System.out.println("请输入第一个数字");
int a=scan.nextInt();//键盘输入a
System.out.println("请输入第二个数字");
int b=scan.nextInt();//键盘输入b
int c=a+b;//int c 将a+b的值赋予c,此行可不写,但需要将下方输出语句括号内改为a+b
System.out.println(a+b);//输出结果
}
}
随堂练习二,输入3个数字,输出数字中最大的值:
package cn.itcast.day07.demo;
import java.util.Scanner;
public class demo3max {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int a=sc.nextInt(); //输入a
int b=sc.nextInt();//输入b
int c=sc.nextInt();//输入c
int d=a>b?a:b;//三元运算符 比较a与b的大小,若a大,d=a,否则d=b
int e=d>c?d:c;//三元运算符 比较d与c的大小,若d大,e=d,否则e=c
System.out.println(e);
}
}
了解匿名对象,
如创建过person类,则使用new person().成员变量;即为匿名对象。
随堂练习
package cn.itcast.day07.demo;
import java.util.Scanner;
public class demo5niming2 {
public static void main(String[] args) {
/* 普通显示键盘输入的内容
Scanner sc = new Scanner(System.in);
String ss = sc.next();
System.out.println(ss);*/
/* 匿名方法-调用无返回值的方法
methodParam(new Scanner(System.in));*/
// 匿名方法-调用有返回值的方法
Scanner sc = sc();
int a=sc.nextInt();
System.out.println(a);
}
public static void methodParam(Scanner sc) {
int i = sc.nextInt();
System.out.println(i);
}
public static Scanner sc(){
return new Scanner(System.in);
}
}
了解Random类,使用方法如下:
随堂练习,随机生成20个数字
package cn.itcast.day07.demo;
import java.util.Random;
public class demo6Random {
public static void main(String[] args) {
Random a=new Random();
for (int i = 0; i < 20; i++) {
int num=a.nextInt(15 );
System.out.println(num);
}
}
}
随堂练习2,随机生成20个范围在1~10的数字(其实也就是将生成的数字结果+1)
package cn.itcast.day07.demo;
import java.util.Random;
public class demo8RandomN {
public static void main(String[] args) {
Random r= new Random();
for (int i = 0; i < 20; i++) {
int num=r.nextInt(10)+1;
System.out.println(num);
}
}
}
随堂练习3,猜数字小游戏,也就是猜一个数字,自动提示数字过大,过小或猜对,首先用while来写(限制只能猜10次,所以加了int w变量,如果不限制次数,删掉 int w=0,以及while末尾的w++,并把while括号内的w<10删除)
package cn.itcast.day07.demo;
import java.util.Random;
import java.util.Scanner;
public class demo9Play {
public static void main(String[] args) {
Random r = new Random();
// 随机生成一个0-9的数字
int num = r.nextInt(10);
// 显示生成的数字,但这一行最好不写!因为是猜数字,直接显示答案不太好。
// System.out.println(num);
int w = 0;
while (w < 10) {
// 从键盘中输入数字
Scanner scan = new Scanner(System.in);
int n = scan.nextInt();
if (n > num) {
System.out.println("数字太大,请重试");
} else if (n < num) {
System.out.println("数字太小,请重试");
} else {
System.out.println("正确!");
break;
}
w++;
}
System.out.println("游戏结束");
}
}
然后使用for循环,替换上面的while语句:
package cn.itcast.day07.demo;
import java.util.Random;
import java.util.Scanner;
public class demo10playfor {
public static void main(String[] args) {
Random r=new Random();
int num=r.nextInt(10);
for (int i = 0; i < 10; i++) {
Scanner scan=new Scanner(System.in);
int num2=scan.nextInt();
if(num2>num)
{
System.out.println("太大了");
}
else if (num2<num)
{
System.out.println("太小了");
}
else
{
System.out.println("正确");
break;
}
}
System.out.println("结束");
}
}
学习ArrayList集合
ArrayList和数组的区别:
数组:长度不可改变;
ArrayList:可以随意变化。
注意:ArrayList<E>中的<E>代表“泛型”,泛型也就是用于装载集合当中的所有元素全都是统一的XX类型。(如统一的String类型等)
泛型只能是引用类型,不能是基本类型。(若直接打印ArrayList,则显示的不是地址值,而是一个[ ]中括号)
ps:从JDK1.7后,右侧尖括号内可以不写内容,但尖括号既然要写,如:
ArrayList<String> strList=new ArrayList<>();
随堂练习,生成一个ArrayL对象,并对其使用add方法添加数据:
package cn.itcast.day07.demo.demo2;
import java.util.ArrayList;
public class demo02ArrayList {
public static void main(String[] args) {
// 创建ArrayList集合对象
ArrayList<String> strList=new ArrayList<>();
System.out.println(strList);// 输出后显示[]
strList.add("小明");// add方法,添加数据
System.out.println(strList);// 输出后显示[赵丽颖]
strList.add("迪丽热巴");
strList.add("古力娜扎");
strList.add("玛尔扎哈");
System.out.println(strList);
}
}
ArrayList中的常用方法有:
根据上面的4个常用方法,做出练习:
package cn.itcast.day07.demo.demo2;
import java.util.ArrayList;
public class Demo03ArratyList {
public static void main(String[] args) {
ArrayList<String> arrstr = new ArrayList<>();
System.out.println(arrstr);
arrstr.add("第0个数据");
arrstr.add("第1个数据");
arrstr.add("第2个数据");
arrstr.add("第3个数据");
System.out.println(arrstr);//[第0个数据, 第1个数据, 第2个数据, 第3个数据]
//删除索引值为1的集合元素
arrstr.remove(1);
System.out.println(arrstr);//[第0个数据, 第2个数据, 第3个数据]
//从集合中获取元素
String str = arrstr.get(2);
System.out.println("第3个元素是"+str);
// 获取集合的长度尺寸,也就是集合中元素的个数
int size = arrstr.size();
System.out.println(size);//3
}
}
然后另建一个类,用于遍历ArrayList,如下:
、
package cn.itcast.day07.demo.demo2;
import java.util.ArrayList;
public class Demo4ArrayEach {
public static void main(String[] args) {
ArrayList<String> arr=new ArrayList<>();
arr.add("迪丽热巴");
arr.add("古力娜扎");
arr.add("玛尔扎哈");
// 遍历集合
for (int i = 0; i < arr.size(); i++) {
System.out.println(arr.get(i));
}
}
}
此外,还有一个问题:如何在集合中添加基本类型的数据?
其实也就是在尖括号内填写对应的“包装类”,对应信息如下:
如添加int类型,也就是使用Integer包装类:
import java.util.ArrayList;
public class Demo5ArrayListBasic {
public static void main(String[] args) {
ArrayList<Integer> arr=new ArrayList<>();
arr.add(0);
arr.add(1);
arr.add(2);
arr.add(3);
System.out.println(arr);
}
}
还有一点知识是:
随堂练习,随机生成6个随机整数(1-33范围),并将数字存储到ArrayList中,并遍历集合。
import java.util.ArrayList;
import java.util.Random;
public class Demo6lianxi1 {
public static void main(String[] args) {
//创建Random对象
Random r=new Random();
//创建ArrayList<Integer>对象
ArrayList<Integer>arr=new ArrayList<>();
//循环6次,把每次生成的随机数 添加到 arr中
for (int i = 0; i < 6; i++) {
int num=r.nextInt(33)+1;
arr.add(num);
}
//遍历集合
for (int i = 0; i < arr.size(); i++) {
System.out.println(arr.get(i));
}
}
}
随堂练习,自定义4个学生对象,添加到集合,并遍历集合
import java.util.ArrayList;
public class Demo7lianxi2 {
public static void main(String[] args) {
student stuOne=new student("小明",1);
student stuTwo=new student("小红",2);
student stuThr=new student("小强",3);
student stuFou=new student("小刚",4);
ArrayList<student> arr=new ArrayList<>();
arr.add(stuOne);
arr.add(stuTwo);
arr.add(stuThr);
arr.add(stuFou);
for (int i = 0; i < arr.size(); i++) {
System.out.println(arr.get(i).getName()+arr.get(i).getAge() );
}
}
}
随堂练习,指定输出内容为{1@2@3@4}
import java.util.ArrayList;
public class Demo8lianxi3 {
public static void main(String[] args) {
ArrayList<Integer> arr = new ArrayList<>();
arr.add(1);
arr.add(2);
arr.add(3);
arr.add(4);
asd(arr);
}
public static void asd(ArrayList<Integer> arrs) {
System.out.print("{");
for (int i = 0; i < arrs.size(); i++) {
if (i < arrs.size() - 1) {
System.out.print(arrs.get(i) + "@");
} else {
System.out.println(arrs.get(i) + "}");
}
}
}
}
随堂练习,随机生成20个数字存储到一个大集合中,然后在使用一个小集合把大集合中的偶数存储起来。
最后遍历输出小集合中存储的偶数。
注:小集合需要自定义为方法。
package cn.itcast.day07.demo.demo2;
import java.util.ArrayList;
import java.util.Random;
public class zijilianxi {
public static void main(String[] args) {
//创建一个大集合存储20个数字
ArrayList<Integer> dajihe=new ArrayList<>();
//创建Random对象生成20个随机数字
Random r=new Random();
// for循环把20个随机数字存储到dajihe 大集合中
for (int i = 0; i < 20; i++) {
//生成范围是1-20的数字
int num=r.nextInt(20)+1;
//把数字存储到dajihe大集合中
dajihe.add(num);
}
// 使用最开始创建的大集合接收xiaojihe方法的返回值xiaojihe
dajihe=xiaojihe(dajihe);
// 使用size()方法显示集合中的元素个数
System.out.println("一共有:"+dajihe.size()+"个偶数");
//通过for循环将dajige大集合中收到的元素数据 遍历输出
for (int i = 0; i < dajihe.size(); i++) {
System.out.println(dajihe.get(i));
}
}
//编写小集合方法
public static ArrayList<Integer> xiaojihe(ArrayList<Integer>big)
{
// 创建小集合存储偶数
ArrayList<Integer> xiaojihe=new ArrayList<>();
//写for循环把20个数字中的偶数存储到xiaojihe小集合中
for (int i = 0; i < big.size(); i++) {
if(big.get(i)%2==0)
{xiaojihe.add(big.get(i));}
}
return xiaojihe;
}
}
2018年8月22日
了解字符串概述与特点
★字符串特点:
1、字符串内容永不可变,可以理解为它是常量;
2、因为字符串内容不可改变,所以字符串是可以共享使用的;
3、字符串效果是相当于是char [ ] 形字符数组,但底层原理是byte字节数组。
创建字符串的方式:
3种构造方法:
1、public String(); 创建一个空白字符串,不含任何内容。
2、public String(char[] array) 根据字符数组的内容来创建对应的字符串。
3、public String(byte[] array)根据字节数组的内容来创建对应的字符串。
如:
public class demo1 {
public static void main(String[] args) {
// 使用空参构造
String str1 = new String();
System.out.println("第一个字符串是" + str1);
//使用char数组创建字符串
char[] arrayChar={'a','b','c'};
String str2=new String(arrayChar);
System.out.println("第二个字符串是" + str2);
//使用byte数组创建字符串
byte[] arrayByte={97,98,99};//ASCII 95=a 96=b 97=c
String str3=new String(arrayByte);
System.out.println("第三个字符串是" + str3);
}
}
1种直接创建方法:
String str4="直接创建";
注:不管String类是否new,它都算是一个字符串对象。
我们已知字符串是可以共享使用的,但如何共享使用呢?
这里我们需要学习字符串常量池的相关知识。
1、String str=“”这种形式的字符串对象,是直接在字符串常量池中,也就是直接写双引号的字符串,才在字符串常量池中。
2、对于基本类型来说 == 是数值的比较;但在引用类型中,==是地址值的比较。
如:
public class demo2 {
public static void main(String[] args) {
String str = "abc";
String str2 = "abc";
char[] arraychar = {'a', 'b', 'c'};
String str3 = new String(arraychar);
System.out.println(str3);
System.out.println(str==str2);//true
System.out.println(str2==str3);//false
System.out.println(str==str3);//false
}
}
了解equals方法,用于比较字符串内容是否相同,下面介绍2个字符串内容比较方法:
1、public boolean equals(Object obj) ,其中的参数可以是任何对象,且参数必须是字符串,内容相同返回true,否则返回false。(任何对象都可以用Object进行接收)
public class Demo1StringEquals {
public static void main(String[] args) {
String str1="hello";
String str2="hello";
char[] arrayChar={'h','e','l','l','o'};
String str3=new String(arrayChar);
System.out.println(str1.equals(str2));//true
System.out.println(str1.equals(str3));//true
System.out.println(str2.equals(str3));//true
System.out.println(str2.equals("hello"));//true
System.out.println("hello".equals(str1));//true
System.out.println("hello".equals("hello"));//true
System.out.println("Hello".equals("hello"));//false
System.out.println("Hello".equals(str1));//false
System.out.println(str1.equals("Hello"));//false
}
}
equals方法具有对称性,也就是 a.equals(b) 和 b.equals(a) 效果是一样的。
如果要拿一个常量和一个变量做比较,推荐把常量写在前面,如 "abc".equals(str),不推荐把变量写在前面,如 str.equals("abc");
如:
这时候会发现,如果把变量str写在前面,且str=null,则会出现空指针异常。
2、public boolean equalsIgnoreCase(String str) 用于比较2个字符串内容是否相同,且忽略大小写。(同样,推荐把常量写在前面)
如:
public class Demo1StringEquals {
public static void main(String[] args) {
String str1 = "hello";
String str2 = "hello";
char[] arrayChar = {'h', 'e', 'l', 'l', 'o'};
String str3 = new String(arrayChar);
String str4 = null;
System.out.println(str1.equalsIgnoreCase("HELLO"));//true
System.out.println(str3.equalsIgnoreCase("HELLO"));//true
System.out.println("HELLO".equalsIgnoreCase(str4));//false
System.out.println(str4.equalsIgnoreCase("HELLO"));//NullPointerException
}
}
了解获取字符串方法。
常用的有4种方法,分别是:
1、length( ) 用于获取字符串长度;
2、charAt(int index) 用于获取字符串中指定索引的单个字符;
3、concat (String str) 将当前字符串和参数字符(这里为 哈哈)串拼接成为返回值新的字符串,也就是拼接到一起;
4、indexOf(String str)用于获取字符串中该参数第一次出现的索引值。
如:
import java.util.Scanner;
public class Demo2StringGet {
public static void main(String[] args) {
String str="abcabcabc";
System.out.println(str.length());
System.out.println(str.concat("我是新增的内容")); //将当前字符串和参数字符(这里为 哈哈)串拼接成为返回值新的字符串,也就是拼接到一起。这里显示 abcabcabc我是新增的内容
Scanner scan=new Scanner(System.in);// 键盘输入:我试试哈啊
String next = scan.next();
System.out.println(next.length());//lenght方法,显示字符串个数,也就是获取字符串长度 这里显示 5
System.out.println(next.charAt(3));// 显示字符串中索引为3的单个字符,这里显示 哈
System.out.println(next.indexOf("哈"));//显示字符串中第一次出现该字符的索引值 这里显示 3,如果没有该字符,则显示 -1
System.out.println(next.concat("哈哈"));//将当前字符串和参数字符(这里为 哈哈)串拼接成为返回值新的字符串,也就是拼接到一起。这里显示 我试试哈啊哈哈
}
}
了解字符串的截取方法,下面介绍2种方法:
1、substring(int index)截取从参数开始,一直到字符串末尾,返回新的字符串。
2、substring(int begin,int end)截取从begin到end的字符串,返回新的字符串。(注:这是左闭右开区间 也就是“[ ) ”)
如:
public class Demo3StringSub {
public static void main(String[] args) {
// 截取从索引值x后的字符串,返回新的字符串
String str="123456789";
String substring = str.substring(5);//截取索引值为5的字符串,返回新的字符串
System.out.println(substring); // 6789
// 截取从索引值x到索引值y的字符串,返回新的字符串
String str2="abcdefghijklmn";
String substring1 = str2.substring(5, 10);// 截取索引值从5到10的字符串
System.out.println(substring1);// fghij
}
}
了解字符串的转换方法,下面介绍3种方法:
1、toCharArray(); 将当前字符串拆分为字符数组作为返回值。
2、getBytes(); 获得前字符串拆底部的字节数组。
3、replace(Charsequence oldstring,Charsequence newstring); 替换,把所有出现的oldstring替换为newstring,返回被替换后的新字符串。
如:
public class Demo4Stringfenge {
public static void main(String[] args) {
//toCharArray(); 将当前字符串拆分为字符数组作为返回值。
String str1="abcde啊";
char[] chars = str1.toCharArray();
for (int i = 0; i < chars.length; i++) {
System.out.println(chars[i]);
}
// getBytes(); 获得前字符串拆底部的字节数组。
String str2="abc";
byte[] bytes = str2.getBytes();
for (int i = 0; i < bytes.length; i++) {
System.out.println(bytes[i]);
}
//replace(Charsequence oldstring,Charsequence newstring); 替换,把所有出现的oldstring替换为newstring,返回被替换后的新字符
String str3="abc,sad,fds";
String replace = str3.replace(",", "-");
System.out.println(replace);//abc-sad-fds
}
}
了解字符串分割方法,下面介绍1种方法:
split(String regex),按照参数规则,将当前字符串分为若干个部分,如:
public class Demo5StringFenge {
public static void main(String[] args) {
String str1="123,456,678";
String[] split = str1.split(","); //以 逗号 分割
// 遍历数组
for (int i = 0; i < split.length; i++) {
System.out.println(split[i]);
//123
//456
//678
}
}
}
随堂练习,创建一个方法,把数组1,2,3按照指定格式拼接成一个字符串,格式为[word1#word2#word3]
public class Demo6Stringplay1 {
public static void main(String[] args) {
int[] arrayint = {1, 2, 3}; //创建数组
String zuizhongdaan = fangfa(arrayint); // 创建对象,调用fangfa方法
System.out.println(zuizhongdaan);
}
public static String fangfa(int[] intarr) {
String str1 = "[";
for (int i = 0; i < intarr.length; i++) {
if (i == intarr.length - 1) {
str1 = str1 + "word" + intarr[i] + "]";
} else {
str1 = str1 + "word" + intarr[i] + "#";
}
}
return str1;
}
}
随堂练习,随机输入字符串,获取各种类型字符的出现的次数:
import java.util.Scanner;
public class Demo7StringCount {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in); // 创建Scanner对象
System.out.println("请输入大写小写数字其他字符");
String str1 = scan.next();//输入字符串
int shuzi = 0;//数字计数
int daxie = 0;//小写计数
int xiaoxie = 0;//小写计数
int qita = 0;//其他计数
char[] chars = str1.toCharArray(); // 把字符串转换为char数组
for (int i = 0; i < chars.length; i++) { //遍历数组
char ch = chars[i]; //获取单个字符
if ('A' <= ch && ch <= 'Z') { //大写
daxie++;
} else if ('a' <= ch && ch <= 'z') {//小写
xiaoxie++;
} else if ('0' <= ch && ch <= '9') {//数字
shuzi++;
} else {//其他
qita++;
}
}
System.out.println("数字" + shuzi);
System.out.println("大写" + daxie);
System.out.println("小写" + xiaoxie);
System.out.println("其他" + qita);
}
}
了解static关键字。
只要用了static关键则,则对应内容不再属于对象,而是属于类的,且凡是本类中的对象,都可共享使用同一份static。
如 ,建立student类,存储姓名,年龄,教师,学号。
package Demo3;
public class student {
private String name;
private int age;
static String room;
private int id;
private static int idc;//id计数器
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public student() {
this.id=++idc;
}
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 student(String name, int age) {
this.name = name;
this.age = age;
this.id=++idc;
}
}
然后再创建另一个类,调用student类(只要定义了一个stu1.room ,则stu2.room的值也为stu1.room赋予的值)
public class demo1 {
public static void main(String[] args) {
student stu1=new student("小明",23);
student stu2=new student("小红",22 );
System.out.println(stu1.getName()+stu1.getAge());
System.out.println(stu2.getName()+stu2.getAge());
stu1.room="101";// 只需要对一个static赋值后,多个对象可共享使用
System.out.println(stu1.getName()+stu1.getAge()+student.room+stu1.getId());
System.out.println(stu2.getName()+stu2.getAge()+student.room+stu2.getId());
}
}
静态方法可以直接用类名.静态方法名即可调用,成员方法必须先new生成对象,在用对象名.成员方法名才可调用:
(在本类中编写的静态方法,并且在本类中调用,则调用对应静态方法时,可省略本类的类名称)
如,我们先创建一个类,分别存储成员方法与静态方法:
public class demo2Static {
public void chengyuanfangfa (){
System.out.println("这是一个成员方法");
}
public static void jingtaifangfa (){
System.out.println("这是一个静态方法!");
}
}
然后我们再创建一个类,分别调用以上两种方法,如:
public class jingtaifangfa {
public static void main(String[] args) {
demo2Static.jingtaifangfa();//静态方法可以直接使用 类名.静态方法名 调用
demo2Static demo2=new demo2Static(); //成员方法需要先生成对象,再用对象名.成员方法名才可调用
demo2.chengyuanfangfa();
}
}
然后,补充一个知识,静态不能直接访问非静态,如:
public class demo2Static {
int num; //成员变量 非静态
static int age; //静态方法
public static void jingtaifangfa() { //静态方法
System.out.println("这是一个静态方法!");
System.out.println(age); //访问静态 正常
System.out.println(num);// 访问成员变量(非静态) 报错
}
}
为什么会这样?因为内存中是先有的静态内容,后有的非静态内容。 也就是先有静态,后有非静态。
同时,静态方法中不能使用this关键字,this代表当前对象,通过谁调用的方法,谁就是当前对象。但是,静态与对象没有关系,所以不能使用this关键字。(静态为什么和对象没有关系?因为静态不需要new,直接调用类名.静态方法名即可)
静态Static内存图,如:
了解数组工具类Arrays的基本用法(此处简单介绍2种)
1、toString(数组),将数组转换为字符串类型,默认格式为:[元素1,元素2,元素3……]。
2、sort(数组),默认按升序排列(从小到大排列)对数组元素进行排列。
如:
import java.util.Arrays;
public class demo4arrays {
public static void main(String[] args) {
//toString(数组),将数组转换为字符串类型,默认格式为:[元素1,元素2,元素3……]。
int[] array={1,23,44,4,2,12};
String string = Arrays.toString(array);
System.out.println(string);
//sort(数组),默认按升序排列(从小到大排列)对数组元素进行排列。
int[] arrayTwo={1,65,2,6,10,33,5};
Arrays.sort(arrayTwo);
System.out.println(Arrays.toString(arrayTwo));
String[] str={"bbb","aaa","ccc"};
Arrays.sort(str);
System.out.println(Arrays.toString(str));
}
}
随堂练习:将一个字符串中的所有字符升序排列,并倒序输出:
首先我们用此前反转数组的思路来做:
import java.util.Arrays;
public class play1 {
public static void main(String[] args) {
String num = "25416971"; //生成一个String数组
char[] chars = num.toCharArray(); //将String输出转化为char数组
Arrays.sort(chars);//将数组chars升序排列
System.out.println(Arrays.toString(chars));//显示升序排列后的数组
for (int min = 0, max = num.length() - 1; min < max; min++, max--) { //与之前的反转数组原理一直
{ char temp = chars[min];
chars[min] = chars[max];
chars[max] = temp;
}
}
System.out.println(Arrays.toString(chars));//讲char数组转化为字符串输出并显示
}
}
然后再用倒序遍历数组的方法来做(此处倒序直接 chars.forr回车即可自动补全for循环代码):
import java.util.Arrays;
public class lianxi2 {
public static void main(String[] args) {
String str="zxc312";
char[] chars = str.toCharArray(); //把数组str转化为字符数组
Arrays.sort(chars);//调用Arrays类中的sort升序排列方法
System.out.println(chars);//升序显示
for(int i=chars.length-1;i>=0;i--) //倒序遍历数组
{
System.out.print(chars[i]);
}
}
}
了解数学工具类Math中的5种常用方法:
1、abs 绝对值
2、ceil 向上取整
3、floor 向下取整
4、round 四舍五入
5、PI 近似圆周率
如:
public class demo1Math {
public static void main(String[] args) {
// 绝对值
System.out.println(Math.abs(-7));//7
System.out.println(Math.abs(6));//6
System.out.println(Math.abs(0));//0
//向上取整
System.out.println(Math.ceil(3.6));//4.0
System.out.println(Math.ceil(1.6));//2.0
//向下取整
System.out.println(Math.floor(2.1));//2.0
System.out.println(Math.floor(0.1));//0.0
System.out.println(Math.floor(1.9));//1.0
//四舍五入
System.out.println(Math.round(4.5));//5
System.out.println(Math.round(4.4));//4
System.out.println(Math.round(0));//0
}
}
(0822疑问-目前尚未解决)但是我在用Math.round()方法对参数四舍五入时,发现了一个问题,比如我把参与设“-4.5”,四舍五入结果为“-4”,感觉哪里不对的样子(正数4.5用Math.round()方法四舍五入后结果为5),以后学习中发现解决该问题的办法,再专门更新这个问题。
随堂练习:
第一种方法:
只取绝对值法:
package demo4;
public class demoplay {
public static void main(String[] args) {
double min=-10.8;
double max=5.9;
int coundt=0;//计数
for (int i=(int)min;i<max;i++){
int abs = Math.abs(i);//直接取绝对值
if(abs>6||abs<2.1) {
System.out.print(abs+" ");
coundt++;
}
}
System.out.println("一共有:"+coundt);
}
}
第二种方法:
先使其所有数字向上取整,使用Math.ceil()方法,然后再取其绝对值。(需将向上取整后的double类型数字,强制转换为int类型)
public class play2 {
public static void main(String[] args) {
double min=-10.8;
double max=5.9;
int count=0;//计数
for(double i=min;i<max;i++) {
double ceil = Math.ceil(i);
int abs = Math.abs((int)ceil);
if (abs>6||abs<2.1) {
System.out.print(abs+" ");
count++;
}
}
System.out.println("有"+count+"个符合要求");
}
}
2018年8月23日
了解“继承”(面向对象三大特征:封装,继承,多态)
继承主要解决的问题是:共性抽取
继承 有父类(也叫基类或超类)与子类(也叫派生类)
要注意,子类继承父类时候,格式是 子类名 extends 父类名。
如,我们定义一个父类fu:
public class fu {
public void fufangfa()
{
System.out.println("父类方法执行");
}
}
再定义一个子类zi:
public class zi extends fu {
}
这时可以看出,子类使用了extends关键字,代表子类zi已经继承了父类fu,然后我们新建一个类,在main方法中调用子类。
主类:
public class Demo1Extends {
public static void main(String[] args) {
zi zi=new zi();//生成子类对象
zi.fufangfa();//调用子类所继承父类的fufangfa方法,显示:父类方法执行
}
}
在父类和子类中,有变量名重复时,有2种访问方法:
1、通过类的对象直接访问成员变量。
2、通过成员方法访问成员变量。
如,父类:
public class fuqin {
private int numfuqin=2;
private int num=200;
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public int getNumfuqin() {
return numfuqin;
}
public void setNumfuqin(int numfuqin) {
this.numfuqin = numfuqin;
}
public void fuqinfangfa(){
System.out.println(num);
}
}
子类:
public class erzi extends fuqin{
private int numerzi=11;
private int num=100;
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public int getNumerzi() {
return numerzi;
}
public void setNumerzi(int numerzi) {
this.numerzi = numerzi;
}
public void erzifangfa (){
System.out.println(num);
}
}
主类:
public class DemoMain {
public static void main(String[] args) {
erzi erzi=new erzi(); //创建子类对象
System.out.println(erzi.getNumfuqin());//子类继承了父类,这里调用子类继承父类的numfuqin变量
System.out.println(erzi.getNumerzi());//输出子类本身的numerzi变量 显示11
fuqin fuqin=new fuqin();//创建父类对象
System.out.println(erzi.getNumfuqin());//父类只能用父类内的内容,没有任何子类的内容
System.out.println(erzi.getNumfuqin());//子类继承父类的numfuqin变量 显示2
System.out.println(erzi.getNumerzi());//子类本身拥有的numerzi变量 显示11
erzi.erzifangfa(); //调用子类它本类中的方法 显示100
erzi.fuqinfangfa();//调用子类父类中的fuqinfangfa方法,显示200
fuqin.fuqinfangfa();//调用父类它本类的方法 显示200
System.out.println(erzi.getNum());//子类中的num(与父类num变量重名) 显示100
System.out.println(fuqin.getNum());//父类中的num(与子类num变量重名) 显示200
}
}
如何区分 局部变量,本类的成员变量和父类的成员变量之间 变量重名的问题?
这里我们学习super关键字,用于访问父类中的成员变量。
如:父类
public class fu {
int num=1;
}
子类:
public class zi extends fu{
int num=10;
public void zizi(){
int num=11;//局部变量
System.out.println(num);//局部变量
System.out.println(this.num);//成员变量
System.out.println(super.num);//父类中的成员变量
}
}
主类:
public class zhu {
public static void main(String[] args) {
zi zi=new zi();//生成zi子类对象
zi.zizi();//调用子类中的zizi方法
//显示11 10 22
}
}
延伸:那如果父类和子类中同时有一个重名的成员方法时,主类要调用该方法,会怎么执行?
答:主类中new了谁,就优先调用谁的该成员方法,如果该类方法中没有,则向上找(也就是子类如果没有,就去父类中找)。
重载Overload 和 重写 Override的区别
然后了解一下继承中方法的覆盖重写的注意事项:
然后学习继承中方法覆盖重写
如,创建一个父类:
public class fu {
public void call(){
System.out.println("打电话");
}
public void send(){
System.out.println("发短信");
}
public void show(){
System.out.println("显示号码");
}
}
创建一个子类,这里的@Override可用于方法重写的检测:
public class zi extends fu {
@Override
public void show(){
super.show();
System.out.println("增加显示头像");
System.out.println("增加显示名字");
}
}
创建主类:
public class demo1 {
public static void main(String[] args) {
fu fu=new fu();
fu.call();
fu.send();
fu.show();
//显示号码
//打电话
//发短信
zi zi=new zi();
zi.call();
zi.send();
zi.show();
//打电话
//发短信
//显示号码
//增加显示头像
//增加显示名字
}
}
然后学习继承中构造方法的访问特点:
重要:在子类构造方法调用父类构造方法时,super关键字必须写在子类构造方法的第一个语句中!!!(且只能有1个super)
如,父类:
public class fu {
public fu()
{
System.out.println("父类无参构造");
}
public fu(int num){
System.out.println("父类有参构造");
}
}
子类:
public class zi extends fu {
public zi(){
super(1);
System.out.println("子类无参构造");
}
}
主类:
public class demo1 {
public static void main(String[] args) {
zi zi = new zi();
/*显示:父类有参构造
子类无参构造*/
}
}
学习super关键字的三种用法:
1、在子类的成员方法中,访问父类的成员变量;
2、在子类的成员方法中,访问父类的成员方法;
3、在子类的构造方法中,访问父类的构造方法;
如,创建父类:
public class fu {
int num=1;//创建父类成员变量
//创建父类成员方法
public void fangfa(){
System.out.println("我是父类的成员方法");
}
//创建父类构造方法
public fu(){
}
}
创建子类:
public class zi extends fu{
int num=2;//创建子类成员变量
@Override
//创建子类成员方法
public void fangfa() {
System.out.println(num);//显示子类成员变量
System.out.println(super.num);//显示父类成员变量
super.fangfa();//显示父类成员方法
}
//创建子类构造方法
public zi(){
super();//访问父类构造方法
}
}
创建主类:
public class zhu {
public static void main(String[] args) {
zi zi=new zi();
zi.fangfa();
/*显示
2
1
我是父类的成员方法
我是子类的成员方法*/
}
}
学习this关键字的三种用法:
(super关键字用来访问父类内容)this关键字用于访问本类内容。
1、在本类的成员方法中,访问本类的成员变量。
2、在本类的成员方法中,访问本类的另一个成员方法。(起到强调作用)
3、在本类的构造方法中,访问本类的另一个构造方法。
this.(...)调用本类中的另一个构造方法时,也同样需要是构造方法的第一个语句!!!(注意 super和this 的构造调用 不可同时使用!)
如,创建子类:
public class Demo1 extends fu{
int num=10;
public void zi(){
int num=20;
System.out.println(num);//显示成员方法中的num 10
System.out.println(this.num);//显示成员变量中的num 20
System.out.println(super.num);//显示父类中的成员变量 30
this.fangfa();//调用本类中的fangfa方法,强调调用的不是父类中的方法!
}
@Override
public void fangfa() {
System.out.println("我是子类的成员方法");
}
}
创建父类:
public class fu {
int num=30 ;
public void fangfa(){
System.out.println("我是父类成员方法");
}
}
创建主类:
public class zhu {
public static void main(String[] args) {
Demo1 zi=new Demo1();
zi.zi();
/*显示
20
10
30
我是子类的成员方法
我是父类成员方法*/
}
}
super与this关键字图解:
下一步,学习了解JAVA继承的3个特点:
1、JAVA语言是单继承的,也就是说一个类的直接父类,只能有1个。
2、JAVA语言可以多级继承。
3、一个子类的直接父类是唯一的,但一个父类,可以拥有很多个子类。
学习了解抽象的概念。
如:
public abstract class demo1 {
public abstract void eat();
}
抽象对象的使用方法:
1、抽象对象不能直接new创建。
2、必须用一个子类继承抽象父类。
3、子类必须 覆盖重写(实现) 抽象父类中所有的抽象方法。
覆盖重写(实现)的意思是:去掉抽象方法中abstract关键字,并把后面方法体大括号补全。
4、创建子类对象进行使用。
如,创建抽象类Demo1:
public abstract class demo1 {
public abstract void eat(); //创建抽象方法eat ,需要在返回值前加abstract关键字
}
创建子类zilei:
public class zilei extends demo1 {
@Override
public void eat() {
System.out.println("我是子类,我的内容是:“猫吃鱼”");
}
}
创建主类:
public class zhu {
public static void main(String[] args) {
zilei zi=new zilei();
zi.eat();
}
}
注意事项:
综上,创建抽象父类1:
public abstract class No1Fu {
public abstract void eat();//创建抽象方法eat
public abstract void sleap();//创建抽象方法sleap
}
创建抽象子类2:
public abstract class No2fu extends No1Fu{
@Override
public void eat() {
System.out.println("狗吃骨头");
}
}
创建子类3:
public class No3zi extends No2fu {
@Override
public void sleap() {
System.out.println("我横着睡");
}
}
创建子类4:
public class No4Zi extends No2fu {
@Override
public void sleap() {
System.out.println("我竖着睡");
}
}
创建主类:
public class main {
public static void main(String[] args) {
No3zi no3=new No3zi();
no3.eat();
no3.sleap();
/*狗吃骨头
我横着睡*/
No4Zi no4=new No4Zi();
no4.eat();
no4.sleap();
/* 狗吃骨头
我竖着睡*/
}
}
随堂练习,群主发普通红包(金额平分),群员抢。
创建用户父类:
public class user {
private String name; //姓名
private int money;// 余额
//展示名字和余额
public void show(){
System.out.println("我是:"+name+",我的余额是:"+money);
} public user() {
}
public user(String name, int money) {
this.name = name;
this.money = money;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getMoney() {
return money;
}
public void setMoney(int money) {
this.money = money;
}
}
创建群主子类:
import java.util.ArrayList;
public class qunzhu extends user {
public qunzhu() {
}
public qunzhu(String name, int money) {
super(name, money);
}
public ArrayList<Integer> send(int totalMonet, int count) { //参数 要发多少钱 分多少份
//先创建集合,存储金额
ArrayList<Integer> redList = new ArrayList<>();
//看群主自己有多少钱
int leftMoney=super.getMoney(); //群主当前余额
if(totalMonet>leftMoney)
{
System.out.println("余额不足!");
return redList;
}
//扣钱
super.setMoney(leftMoney-totalMonet);
//发红包需要分为count份
int avg=totalMonet/count;
//求余,把余数放在最后1个红包里
int mod=totalMonet%count;
//遍历 把红包放进集合
for (int i = 0; i < count-1; i++) {
redList.add(avg);
}
//把最后的余数放进最后1个红包
int last=avg+mod;
redList.add(last);
return redList;
}
}
创建群员子类:
import java.util.ArrayList;
import java.util.Random;
public class qunyuan extends user {
public qunyuan() {
}
public qunyuan(String name, int money) {
super(name, money);
}
public void receive(ArrayList<Integer> list){
//获取集合的一个 随机 索引编号
// int index=new Random().nextInt(list.size());
Random ran=new Random();
int index = ran.nextInt(list.size());
// 获取被删除的索引值对应的集合元素
int delta = list.remove(index);
//查看自己有多少钱
int money = super.getMoney();
//重新设置回去金额
super.setMoney(money + delta);
}
}
创建主类:
import java.util.ArrayList;
public class main {
public static void main(String[] args) {
qunzhu qunzhu=new qunzhu("群主",100);
qunzhu.show();
qunyuan one=new qunyuan("群员A",0);
qunyuan two=new qunyuan("群员B",0);
qunyuan three=new qunyuan("群员C",0);
one.show();
two.show();
three.show();
System.out.println("============");
//群主发红包
ArrayList<Integer> hongbao=qunzhu.send(20,3);
//收红包
one.receive(hongbao);
two.receive(hongbao);
three.receive(hongbao);
qunzhu.show();
one.show();
two.show();
three.show();
}
}
结果显示:
我是:群主,我的余额是:100
我是:群员A,我的余额是:0
我是:群员B,我的余额是:0
我是:群员C,我的余额是:0
============
我是:群主,我的余额是:80
我是:群员A,我的余额是:6
我是:群员B,我的余额是:8
我是:群员C,我的余额是:6
2018年8月24日
今天学习“接口”,接口其实是一种公共规范。(接口是一种引用数据类型,最重要的内容就是其中的抽象方法 abstract)
接口定义的基本格式(接口名称与类格式一样,大驼峰,首字母大写)
public interface 接口名称{
//接口内容 }
接口的基本使用步骤:
1、接口不能直接使用,也就是不能直接new接口,如果要使用,需要一个实现类来实现该接口。
如:public class 实现类名称 implements 接口名称{ };
2、接口的实现类,必须 覆盖重写 接口中 所有的 抽象方法(去掉abstract关键字,在末尾加上{}大括号与方法体)。
3、创建实现类的对象进行使用。
如,创建接口:
public interface jiekou {
public abstract void jiekouone();
public abstract void jiekoutwo();
public abstract void jiekouthree();
}
创建实现类,一定要按格式 public class实现类名称 interface 接口类{ }:
public class shixianlei implements jiekou{
// 覆盖重写所有接口类中所有抽象方法
@Override
public void jiekouone() {
System.out.println("我是接口1");
}
@Override
public void jiekoutwo() {
System.out.println("我是接口2");
}
@Override
public void jiekouthree() {
System.out.println("我是接口3");
}
}
创建主类:
public class main {
public static void main(String[] args) {
//创建实现类对象
shixianlei sx=new shixianlei();
sx.jiekouone();
sx.jiekoutwo();
sx.jiekouthree();
}
}
学习了解 接口的【默认方法】 的定义格式:
public default 返回值类型 方法名(参数列表) {
方法体
}
备注:默认方法,可以解决接口升级的问题。
如创建接口类:
public interface jiekou {
//创建抽象方法
public abstract void jiekouone();
//创建默认方法
public default void morenfangfa (){
System.out.println("我是默认方法");
}
}
创建实现类1:
public class shixianlei1 implements jiekou{
@Override
public void jiekouone() {
System.out.println("我是接口中的抽象方法");
}
}
创建接口类2:
public class shixianlei2 implements jiekou{
@Override
public void jiekouone() {
System.out.println("我是接口中的抽象方法");
}
@Override
public void morenfangfa() {
System.out.println("我覆盖重写默认方法");
}
}
创建主类:
public class main {
public static void main(String[] args) {
//创建shixianlei1对象
shixianlei1 x1=new shixianlei1();
x1.jiekouone(); //我是接口中的抽象方法
//创建shixianlei2对象
shixianlei2 x2=new shixianlei2();
x2.jiekouone(); //我是接口中的抽象方法
x2.morenfangfa(); //我覆盖重写默认方法
}
}
学习了解【接口中的静态方法】的定义格式。
例:public static 返回值类型 方法名(参数列表){ 方法体 }
在接口中定义静态方法,如:
public interface jiekou {
public static void jingtai(){
System.out.println("静态方法");
}
}
然后可以直接在主类中,通过 接口名.静态方法名(参数列表);直接调用!!不要去创建实现类对象去调用接口中的静态方法,会报错的!
正确调用格式如:
public class main {
public static void main(String[] args) {
//直接通过接口名.静态方法名调用
jiekou.jingtai();//静态方法
}
}
学习了解【接口中如何定义私有(private)方法】
下面我们分别介绍普通私有方法与私有静态方法的解决方案:
普通私有方法:解决接口中多个默认方法总的重复代码问题。
创建接口类:
public interface jiekou {
public default void morenOne(){
System.out.println("我是默认A");
System.out.println("AAA");
System.out.println("BBB");
System.out.println("CCC");
}
public default void morenTwo(){
System.out.println("我是默认B");
System.out.println("AAA");
System.out.println("BBB");
System.out.println("CCC");
}
}
这时,我们会发现,接口中的2个默认方法 morenOne与morenTwo中输出的AAA/BBB/CCC都是重复的,因此我们需要在定义一个私有方法将重复代码放置进入,然后在默认方法中调用接口本类中的私有方法,如:
public interface jiekou {
public default void morenOne() {
System.out.println("我是默认A");
chongfu();
}
public default void morenTwo() {
System.out.println("我是默认B");
chongfu();
}
private void chongfu() {
System.out.println("AAA");
System.out.println("BBB");
System.out.println("CCC");
}
}
创建实现类:
public class main implements jiekou {
}
然后创建主类,我们可以发现,创建实现类对象后,无法通过实现类对象访问接口中的private私有方法:
public class main2 {
public static void main(String[] args) {
main m = new main();
m.morenOne();
m.morenTwo();
/* 我是默认A
AAA
BBB
CCC
我是默认B
AAA
BBB
CCC*/
}
}
然后是第二种情况,静态私有方法:解决多个静态方法中重复的代码问题。
创建接口类:
public interface jiekou {
public static void morenOne() {
System.out.println("我是默认A");
chongfu();
}
public static void morenTwo() {
System.out.println("我是默认B");
chongfu();
}
private static void chongfu() {
System.out.println("AAA");
System.out.println("BBB");
System.out.println("CCC");
}
}
我们要知道,静态static方法,可以直接通过类名.方法名调用,这里我们可以直接在主类中通过接口名.静态方法名调用,如主类:
public class main2 {
public static void main(String[] args) {
jiekou.morenOne();
jiekou.morenTwo();
/*我是默认A
AAA
BBB
CCC
我是默认B
AAA
BBB
CCC*/
}
}
我们依然可以发现,无法通过接口名.方法名访问接口中的private私有方法。
接口中可以定义“成员变量”
如,创建接口:
public interface jiekou {
public static final int NUM_SHIER=12;
}
创建主类:
public class main {
public static void main(String[] args) {
System.out.println(jiekou.NUM_SHIER);
}
}
接口内容小结:
在java9+版本中,接口的内容可以有:
1、接口中的“成员变量”其实就是“常量”,为什么说它的常量?因为接口中的成员变量必须赋值!所以它就是“常量”。
如:public static final int NUM_ONE=1; (public static final 可以不写,但常量名必须用大写,且需用下划线进行分隔)
2、接口中,最重要的就是 抽象方法,格式如下:
public abstract 返回值类型 方法名();
注:接口的实现类,必须覆盖重写所有的抽象方法,否则,它必然是一个抽象类!
3、从java8开始,接口中允许定义 默认方法 ,格式如下:
public default 返回值类型 方法名(参数列表){
方法体
}
注:默认方法也可以被实现类覆盖重写!若不写,则直接调用接口中的默认方法即可。
4、从java8开始,接口中允许定义 静态方法,格式如下:
public static 返回值类型 方法名(参数列表){
方法体
}
注:接口中的静态方法 应通过 接口名.静态方法名进行调用,不能通过创建实现类对象调用接口中的静态方法。
5、从java9开始,接口里允许定义 私有方法,格式如下:
a/ 普通私有方法:private 返回值类型 方法名(参数列表){方法体}
b/静态私有方法:private static 返回值类型 方法名(参数列表){方法体}
注:private方法只有自己本类才可调用,不能通过实现类调用。
接口之间的多级继承
创建接口1,如:
public interface jiekou1 {
public abstract void jiekouB();
}
创建接口2,如:
public interface jiekou2 {
public abstract void jiekouA();
}
创建接口3,继承接口1和2,如:
public interface jiekou3 extends jiekou1,jiekou2 {
public abstract void jiekou3();
}
创建实现类,调用接口jiekou3即可同时调用到jiekou3的父类接口
public class shixianlei implements jiekou3 {
@Override
public void jiekou3() {
}
@Override
public void jiekouB() {
}
@Override
public void jiekouA() {
}
}
多态性:
创建父类对象,如:
public class fu {
public void method(){
System.out.println("我是父类方法");
}
public void fulei(){
System.out.println("父类独有");
}
}
创建子类,如:
public class zi extends fu{
@Override
public void method() {
System.out.println("子类方法");
}
}
创建主类,如:
public class main {
public static void main(String[] args) {
//多态写法,左侧父类引用 指向右侧子类的对象
fu obj=new zi();
obj.method();//子类方法
obj.fulei();//父类独有
}
}
成员的向上转型和向下转型
创建父类animal,如:
public abstract class animal {
public abstract void eat();
}
创建子类 猫:
public class mao extends animal {
@Override
public void eat() {
System.out.println("猫吃鱼");
}
public void maomi(){
System.out.println("我是猫的独有方法");
}
}
创建子类 狗:
public class dog extends animal {
@Override
public void eat() {
System.out.println("狗吃屎");
}
public void gouzi(){
System.out.println("我是狗的独有方法");
}
}
创建主类:
public class main {
public static void main(String[] args) {
animal dongwu =new mao();//猫向上转性为动物
dongwu.eat();//猫吃鱼
mao mao=(mao)dongwu; //动物向下转型为毛,因为它本来就是猫
mao.maomi();//我是猫的独有方法
dog dog=(dog)dongwu;//报错 类转换异常
dog.gouzi(); //报错
}
}
我们会发现,主类中 animal dongwu=new mao();
猫的对象向上转型为动物,然后调用猫的eat方法;
然后通过 :子类名称 对象名=(子类名称)父类的对象名;
将父类动物 向下转型为 猫,并调用猫的maomi方法;
但下一行的 dog dog=(dog)dongwu; 运行时则会报错,提示类转换异常,因为动物animal本来是new了一只猫,所以它只能向下还原为猫,不能还原为狗。
2018年8月25日
随堂练习,笔记本USB接口案例(今天有事,只能学这么点)
示意图:
创建USB接口:
public interface USB {
public abstract void open();//打开USB
public abstract void close();//关闭USB
}
创建鼠标类:
public class Mouse implements USB {
@Override
public void open() {
System.out.println("打开鼠标");
}
@Override
public void close() {
System.out.println("关闭鼠标");
}
public void click(){
System.out.println("点鼠标");
}
}
创建键盘类:
public class KeyBoard implements USB {
@Override
public void open() {
System.out.println("打开键盘");
}
@Override
public void close() {
System.out.println("关闭键盘");
}
public void keyjianpan(){
System.out.println("拍键盘");
}
}
创建电脑类:
public class Pc {
public void kaiji(){
System.out.println("笔记本开机");
}
public void usbUsb(USB usb)
{
/* Mouse mouse=new Mouse();
mouse.open();
mouse.close();*/
if(usb instanceof KeyBoard)
{KeyBoard jianpan=(KeyBoard)usb;
jianpan.open();
jianpan.keyjianpan();
jianpan.close();
}
else if(usb instanceof Mouse)
{
Mouse shubiao=(Mouse)usb;
shubiao.open();
shubiao.click();
shubiao.close();
}
}
public void guanji(){
System.out.println("笔记本关机");
}
}
创建主类:
public class main {
public static void main(String[] args) {
Pc pc=new Pc();
pc.kaiji();//笔记本开机
//键盘向上转型
USB usbKeyBoard=new KeyBoard();
//调用pc的usbUsb方法,将usbKeyBoard传参
pc.usbUsb(usbKeyBoard);
//创建Mouse对象
Mouse mouse=new Mouse();
//mouse传参,自动发生了合法的向上转型
pc.usbUsb(mouse);
pc.guanji();//笔记本关机
}
}