1、抽象类
抽象类的概念:
包括抽象方法的类,用abstract修饰
抽象方法的概念:
只有方法声明,没有方法体的方法,用abstract修饰
抽象方法的由来:
当需要定义一个方法,却不明确方法的具体实现时,可以将方法定义为abstract,具体实现延迟到子类
package cn.itcast.demo7;
public class Test {
public static void main(String[] args) {
//测试狗类
Dog d = new Dog();
d.eat();
//测试老鼠类
Mouse m = new Mouse();
m.eat();
System.out.println("------------");
//通过多态测试
Animal an = new Dog();
an.eat();
Animal a = new Mouse();
a.eat();
}
}
package cn.itcast.demo7;
//父类(抽象类)
public abstract class Animal {
//抽象方法 (特点:要求子类必须重写)
public abstract void eat();
}
package cn.itcast.demo7;
//子类
public class Dog extends Animal{
//alt+enter 快捷键自动生成方法
@Override
public void eat() {
System.out.println("狗吃骨头");
}
}
package cn.itcast.demo7;
//子类
public class Mouse extends Animal {
@Override
public void eat() {
System.out.println("老鼠吃奶酪");
}
}
抽象类的特点:
- 修饰符:必须用abstract关键字修饰;修饰符abstract class 类名{};修饰符abstract 返回类型 方法名{}。
- 抽象类不能被实例化(new),只能创建子类对象。
- 抽象类子类的两个选择:重写父类所有抽象方法;定义成抽象类。
抽象类成员特点:
- 成员变量:可以有普通的成员变量,也可以有成员常量(final)。
- 成员方法:可以有普通方法,也可以有抽象方法;抽象类不一定有抽象方法,有抽象方法的类一定是抽象类(或接口)。
- 构造方法:像普通类一样有构造方法,且可以重载。
- 总结:抽象类中的成员比普通类多一种——抽象方法,其他和普通类一样。
package cn.itcast.demo7;
public class Test {
//Animal an = new Animal(); 这样写是错误的
public static void main(String[] args) {
//初始化抽象类
Animal an = new Cat();
System.out.println("-------------");
//抽象类的成员特点
an.name = "Tom";
System.out.println("-------------");
// an.AGE = 50; 代码报错原因:常量的值不可改变
System.out.println(an.AGE);
}
}
package cn.itcast.demo7;
//父类(抽象类)
public abstract class Animal {
//构造方法
public Animal(){}
public Animal(String name){
this.name = name;
}
//成员变量:其值可以变化
String name = "HaShiQi";
//成员常量:气质不能改变
final int AGE = 30;
//吃
public abstract void eat();
//睡
public abstract void sleep();
public void call(){
System.out.println("动物会叫");
}
}
package cn.itcast.demo7;
//子类
public class Cat extends Animal{
@Override
public void eat() {
System.out.println("猫吃鱼");
}
@Override
public void sleep() {
System.out.println("猫躺着睡");
}
}
package cn.itcast.demo7;
//子类
public abstract class Dog extends Animal{
}
//小细节:在实际开发中,子类一般都有两个构造方法
//子类的空参构造访问父类的空参构造
//子类的全参构造访问父类的全参构造
final关键字
- 修饰类: 该类不能被继承 ,但是可以继承别的类。
- 修饰方法:该方法不能被重写,不能与abstract共存。
- 修饰变量:对于基本类型的变量,其值不能改变;对于引用类型的量,不能改变其地址值,但是可以改变其属性值。
static关键字
- 概念:静态的。
- 作用:用于修饰类的成员——成员方法:类方法;成员变量:类变量。
- 调用方式:类名.成员变量名;类名.成员方法名(参数)
- static修饰成员变量的特点:被本类所有对象共享
- 注意:随意修改静态变量的值是有风险的,为了降低风险,可以同时用final关键字修饰,即公有静态常量(注意命名的变化)
package cn.itcast.demo8;
public class Test {
//需求:定义研发部成员类,让每位成员进行自我介绍
public static void main(String[] args) {
Developer d1 = new Developer();
d1.name = "XiaoHei";
d1.work = "XieDaiMa";
d1.selfIntroduction();
Developer d2 = new Developer();
d2.name = "YuanYuan";
d2.work = "GuLiShi";
d2.selfIntroduction();
System.out.println("------------");
//
// Developer.departmentName = "KaiFaBu";
}
}
package cn.itcast.demo8;
//开发者类
public class Developer {
//成员变量
String name;
String work;
//公共的静态常量
public final static String DEPARTMENT_NAME = "YanFaBu";
//成员方法
public void selfIntroduction(){
System.out.println("我是" + DEPARTMENT_NAME + "的" + name +",我的工作是" + work);
}
}
- static修饰成员方法
- 静态方法:静态方法中没有对象this,所有不能访问非静态成员
- 静态方法的使用场景:只需要访问静态成员;不需要访问对象状态,所有参数由参数列表显示提供
接口:
- 接口的定义:定义接口使用关键字interface——interface 接口名 {};类和接口是实现关系,用implements表示——class 类名 implements 接口名
package cn.itcast.demo8;
public class Test {
public static void main(String[] args) {
//
Smoking s = new Teacher();
s.smoke();
}
}
package cn.itcast.demo8;
//接口
public interface Smoking {
//
public abstract void smoke();
}
package cn.itcast.demo8;
public class Teacher implements Smoking {
@Override
public void smoke() {
System.out.println("抽烟有害健康!");
}
}
- 接口创建对象的特点:接口不能实例化——通过多态的方式实例化子类对象;接口的子类(实现类)——可以是抽象类,也可以是普通类。
- 接口继承关系的特点:接口与接口之间的关系——继承关系,可以多继承,格式——接口 extends 接口1,接口2,…
- 接口与实现的区别:继承体现的是“is a”的关系,父类中定义共性内容;实现体现的是“like a”的关系,接口中定义扩展功能。
- 接口与类之间的关系:类与类之间——继承关系,只能单继承,不能多继承,但是可以多层继承。类与接口之间——实现关系,可以单实现,也可以多实现。接口与接口之间——继承关系,可以单继承,也可以多继承。
- 接口不能实例化,需要创建其子类对象来完成实例化操作。
- 接口的子类,如果是普通类,则必须重写接口中的所有抽象方法;如果是抽象类,则不用重写接口中的抽象方法;
- 接口成员变量的特点:接口没有成员变量,只有公有的、静态的常量——public static final 常量名 = 常量值
- 成员方法:public abstract 返回值类型 方法名{}
- 构造方法的特点:接口不能实例化,也没有需要初始化的成员,所以接口没有构造方法
2、API
- API:是Java中提供的类的说明书
- Java中组件的层次结构:模块(是包的容器)—> 包—> 类或接口
Object类
- 简介:类层次结构最顶层的基类,所有类都直接或间接地继承自Object类,所以,所有的类都是一个Object(对象)
- 构造方法:Object()—— 构造一个对象,所有子类对象初始化时都会优先调用该方法。
- 成员方法:
- int hashCode() —— 返回对象的哈希码值,该方法通过对象的地址值进行计算,不同对象的返回值一般不同。
- Class<?>getClass —— 返回调用此方法对象的运行时类对象(调用者的字节码文件对象),一个类只有一个字节码文件对象。
- String toString() —— 返回该对象的字节串表示,默认打印的是地址值,但是不同对象的地址值肯定不同;地址值的组成——全类名 + @ + 该对象的哈希码的无符号十六进制形式
- boolen equals() —— 返回其他某个对象是否与此对象“相等”,默认情况下比较两个对象的地址值,无意义,建议重写。
- 注意:java.lang包下的类可以直接使用,不需要导包;
package cn.itcast.demo8;
public class Test {
public static void main(String[] args) {
//非静态方法的调用方式——对象名.
Object o1 = new Object();
Object o2 = new Object();
int code1 = o1.hashCode();
int code2 = o2.hashCode();
System.out.println(code1);
System.out.println(code2);
System.out.println("------------");
Class clazz1 = o1.getClass();
Class clazz2 = o2.getClass();
System.out.println(clazz1);
System.out.println(clazz2);
System.out.println("------------");
String s1 = o1.toString();
String s2 = o2.toString();
System.out.println(s1);
System.out.println(s2);
boolean b1 = o1.equals(o2);
System.out.println(b1);
}
}
/*
class Person {
}
class Student extends Person{
}*/
JavaBean重写Object类的方法
package cn.itcast.demo8;
/*
需求:一个标准的JavaBean类,并在测试类中进行测试
学生类:Student
属性:id,name,score
*/
public class Test {
public static void main(String[] args) {
Student s1 = new Student(1,"OuYangXiu",66);
//输出语句直接打印对象,默认是调用了该对象的toString()方法
System.out.println(s1);
System.out.println(s1.toString());
Student s2 = new Student(1,"OuYangXiu",66);
boolean b1 = s1.equals(s2);
System.out.println(b1);
}
}
package cn.itcast.demo8;
import java.util.Objects;
public class Student {
//成员变量
private int id;
private String name;
private int score;
//构造方法
public Student() {
}
public Student(int id, String name, int score) {
this.id = id;
this.name = name;
this.score = score;
}
//成员方法
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
}
//equals()
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return id == student.id &&
score == student.score &&
name.equals(student.name);
}
@Override
public int hashCode() {
return Objects.hash(id, name, score);
}
//toString
@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
", score=" + score +
'}';
}
}
- 在一般的JavaBean中都会重写toString() 和equals()
Scanner类
- 构造方法:Scanner(InputStream)—— 构造一个扫描器对象,从制定输入流中获取数据参数System.in,对应键盘录入
- 成员方法:hasNextXxx () —— 判断是否还有下一个输入项,其中Xxx可能是任意基本数据类型,返回结果为布尔类型;nextXxx () ——获取下一个输入项,其中Xxx可能是任意基本数据类型,返回对应类型的数据;String nextLine () :获取下一行的数据,以换行符作为分割符;String next () —— 获取下一个输入项,以空白字符作为分割符空白字符:空格、tab、回车等。
package cn.itcast.demo8;
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
//System.in:标准的输入流,默认指向键盘
Scanner sc = new Scanner(System.in);
//接收整数
System.out.println("请输入一个整数");
if (sc.hasNextInt()){
int num = sc.nextInt();
System.out.println("num: " + num);
}
//接收字符串
System.out.println("请输入一个字符串");
String str1 = sc.nextLine();
System.out.println("str1; "+ str1);
}
}
string类的判断功能
- 构造方法: String(byte[]) —— 构造一个String对象,将指定字节数组中的数据转化成字符串;String(char[]) —— 构造一个String对象,将指定字符数组中的数据转化成字符串。
- 成员方法:boolean equals(String) —— 判断当前字符串与给给定字符串是否相同,区分大小写;oolean equalsIgnoreCase(String) —— 判断当前字符串与给给定字符串是否相同,区分大小写;bollean startsWith(String):判断是否以给定字符串开头。
package cn.itcast.demo8;
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
//测试 构造方法
//1、将指定的字节数组转成字符串
//'a' = 97
byte[] bys = {97,98,99};
String s1 = new String(bys);
System.out.println("s1: " + s1);
//2、将指定的字符数组转成字符串
char[] chs = {'h','e','l','l','o'};
String s2 = new String(chs);
System.out.println("s2: " + s2);
//在实际开发中,String类非常常用,每次都new很麻烦,于是针对于String的语法做了优化,省去了new的动作
String s3= "abc"; //免new
// String s4 = new String("abc");
System.out.println("--------------");
//测试成员方法
String str1 = "aba";
String str2 = "ABC";
boolean b1 = str1.equals(str2); //区分大小写
System.out.println("equals(): " + b1);
boolean b2 = str1.equalsIgnoreCase(str2); //不区分大小写
System.out.println("equalsIgnoreCase: " + b2);
boolean b3 = str1.startsWith("a");
System.out.println("startsWith(): " + b3);
String str3 = "hello";
boolean b4 = str3.isEmpty();
System.out.println("isEmpty(): " + b4);
}
}
string类的获取功能
成员方法:
- int length():获取当前字符串的长度;
- char charAt(int index):获取指定索引位置的字符;
- int indexOf(String):获取指定字符(串)第一次出现的索引;
- int lastIndexOf(String):获取指定字符(串)最后一次出现的索引;
- String substring(int):获取指定索引位置(含)之后的字符串;
- String substring(int,int):获取指定索引位置(含)起至索引end位置(不含)的字符串;
package cn.itcast.demo8;
public class Test {
public static void main(String[] args) {
String str = "Java 黑马程序员 java";
// int length = str.length();
// System.out.println(length);
System.out.println(str.length());
System.out.println(str.charAt(1));
int index1 = str.indexOf('a');
System.out.println("indexOf: " + index1);
int index2 = str.lastIndexOf('a');
System.out.println("lastIndexOf: " + index2);
String s1 = str.substring(5);
System.out.println("substring1: " + s1);
String s2 = str.substring(5,10);
System.out.println("substring2: " + s2);
}
}
string类的转换功能
成员方法:
- byte[] getBytes():将字符串转换成字节数组
- char[] toCharArray():将字符串转换成字符数组
- static String valueOf(…):将指定类型数据转换成字符串
- String replace(old,new):将指定字符(串)替换成新的字符(串)
- String[] split(String):切割字符串,返回切割后的字符串数据,原字符串不变
- String trim():去除字符串两端的空白字符
package cn.itcast.demo8;
public class Test {
public static void main(String[] args) {
String s1 = "abc";
byte[] bys = s1.getBytes();
for (int i = 0; i < bys.length; i++) {
System.out.println(bys[i]);
}
System.out.println("-------------");
char[] chs = s1.toCharArray();
for (int i = 0; i < bys.length; i++){
System.out.println(chs[i]);
}
System.out.println("-------------");
String s2 = String.valueOf(123);
System.out.println(s2 + 4);
//在实际开发中,上述的方式基本上都会用下边的这行代码替代
String s3 = "" + 123;
System.out.println(s3 + 4);
System.out.println("-------------");
String s4 = "abc abc abc";
//用d替换b
String s5 = s4.replace('b','d');
System.out.println(s5);
System.out.println("-------------");
String[] arr = s4.split(" ");
for (int i = 0; i < bys.length; i++){
System.out.println(arr);
}
System.out.println("-------------");
String s6 = " a b c ";
String s7 = s6.trim();
System.out.println(s6);
System.out.println(s7);
}
}
StringBuilder和StringBuffer类
简介:
可变字符序列,用于构造字符串对象。内部使用自动扩容的数组操作字符串数据。StringBuilder和StringBuffer使用相同的API
构造方法:
- StringBuilder():构造一个空的StringBuilder容器
- StringBuilder(String):构造一个StringBuilder容器,并添加指定字符串
成员方法:
- StringBuilder append(…):将任意数据添加到StringBuilder容器中,返回自身。
- String toString():将当前StringBuilder容器转成字符串
package cn.itcast.demo8;
public class Test {
public static void main(String[] args) {
StringBuilder sb = new StringBuilder();
// StringBuilder sb2 = sb.append("abc");
sb.append("abc");
System.out.println(sb);
// System.out.println(sb2);
System.out.println("-----------------");
StringBuilder sb3 = new StringBuilder("abc");
System.out.println(sb3);
System.out.println("-----------------");
//需求:将三个字符串拼接到一个字符串
StringBuilder sb4 = new StringBuilder();
sb4.append("学Java");
sb4.append("来这里,");
sb4.append("找小黑!");
System.out.println(sb4);
System.out.println("-----------------");
String s = sb4.toString();
System.out.println(s);
}
}
Date类和Calendar类
简介:
日期和日历类,用于操作日期相关信息
构造方法:
- Date():构造一个日期对象,当前系统时间,精确到毫秒
- Date(long):构造一个日期对象,时间为自 “1970年1月1日 00:00:00 GMT” 起,至指定参数的毫秒数
成员方法:
- long getTime():将日期对象转换成对应的毫秒值
- static Calendar getInstance():根据当前系统时区和语言环境获取日历对象
- int get(int field):返回给定日历字段的值
- void set(int field,int value):将给定的日历字段设置为指定的值
package cn.itcast.demo8;
import java.util.Calendar;
import java.util.Date;
public class Test {
public static void main(String[] args) {
//测试Date类
Date date1 = new Date();
System.out.println(date1);
long time = date1.getTime();
System.out.println(time);
Date date2 = new Date(1581768235123L);
System.out.println(date2);
System.out.println("----------------");
//测试Calendar类
Calendar c = Calendar.getInstance();
System.out.println(c);
System.out.println("----------------");
//java中用0-11表示1-12月
int year = c.get(Calendar.YEAR);
int month = c.get(Calendar.MONTH);
int day = c.get(Calendar.DATE);
System.out.println(year +"年"+ month +"月"+ day +"日");
System.out.println("----------------");
/* //设置年份为2022
c.set(Calendar.YEAR,2022);
int year2 = c.get(Calendar.YEAR);
System.out.println(year2 +"年"+ month +"月"+ day +"日");*/
c.set(2022,1,15);
int year2 = c.get(Calendar.YEAR);
int month2 = c.get(Calendar.MONTH);
int day2 = c.get(Calendar.DATE);
System.out.println(year2 +"年"+ month2 +"月"+ day2 +"日");
}
}
基本类型的包装类
简介:
基本数据类型不是对象,所以Java针对基本类型提供了对应的包装类,以对象的形式来使用。
- 装箱:基本欸写转包装类型(对象类型)
- 拆箱:包装类型(对象类型)转基本类型
成员方法:
- statix 基本类型 parseXxx(String):将字符串类型的数据转换成对应的基本类型
- 注意:除了Character类以外,其他的7中包装类都有parseXXX()方法,因为如果字符串想转换成char类型的数据,可以通过:String类中的方法toCharArray(),charAt()。
package cn.itcast.demo8;
public class Test {
public static void main(String[] args) {
//因为变量a属于基本类型,不能通过对象名.的形式调用方法
//解决方法:将起转换成对应的 包装类(引用类型)即可
int a = 10 ;
//装箱
Integer i1 = new Integer(a);
//拆箱
int b = i1.intValue();
System.out.println(i1);
System.out.println(b);
System.out.println("---------------");
//自动拆装箱
Integer i2 = 30; //装箱
int c = i2; //拆箱
String s = "10";
int num = Integer.parseInt(s);
System.out.println(num);
System.out.println(num +100);
System.out.println("----------------");
}
}
集合
简介: 是用来存储多个元素的容器。
集合和数组的区别:
1.元素类型
集合——引用类型(存储基本类型时自动装箱)
数组——基本类型,引用类型
2.元素个数
集合——不固定,可任意扩容
数组——固定,不能改变容器
3.集合的好处
不受容器大小限制,可以随时添加、删除元素,提供了大量操作元素的方法(判断、获取等)
Java的集合体系:
1.单列集合
List——ArrayList
Set——HashSet
2.双列集合
Map——HashMap
List集合的特点和应用
List集合的特点: 可重复、有序(存取顺序相同)
应用: List list = new ArrayList();
List接口中的成员方法:
1.public boolean add (E e):将数据添加到集合的末尾,这里的E是泛型的意思,目前先理解Object类型。
2.public E get (int index):根据索引,索取其对应的元素
3.public int size ():获取集合的长度
使用集合的步骤:
1.创建集合对象
2.创建元素对象
3.将元素对象添加到集合对象中
4.遍历对象
package cn.itcast.demo8;
import java.util.ArrayList;
import java.util.List;
public class Test {
public static void main(String[] args) {
//需求:往List集合中添加3个学生对象,然后遍历
//1
List list = new ArrayList();
//2
Student s1 = new Student("Q",18);
Student s2 = new Student("Q",18);
Student s3 = new Student("W",24);
Student s4 = new Student("E",54);
//3
/*boolean b1 = list.add(s1);
System.out.println(b1);
boolean b2 = list.add(s2);
System.out.println(b2);*/
list.add(s1);
list.add(s2);
list.add(s3);
list.add(s4);
System.out.println(list);
System.out.println("---------------");
Object obj = list.get(2);
System.out.println(obj);
System.out.println("---------------");
System.out.println(list.size());
System.out.println("---------------");
for (int i = 0; i< list.size();i++){
Object obj2 = list.get(i);
System.out.println("索引为" + i + "的元素是" + obj2);
}
}
}
package cn.itcast.demo8;
//学生类
public class Student {
private String name;
private int age;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = 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;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
增强for循环的使用
增强for循环的格式:
for ( 数据类型 变量名 :数组或者集合对象){
// 循环体,变量即元素
}
快捷方式: iter + enter
package cn.itcast.demo8;
import java.util.ArrayList;
import java.util.List;
public class Test {
public static void main(String[] args) {
List list = new ArrayList();
list.add(10);
list.add(10);
list.add(20);
list.add(30);
list.add(40);
for(Object obj : list){
//obj是集合中的元素,其本身应该是Integer类型的数据
Integer ii = (Integer)obj;
System.out.println(ii);
}
System.out.println("------------------");
for (Object o : list) {
System.out.println(o);
}
}
}
迭代器演示
迭代器的常用方法:
1.next():返回迭代的下一个元素对象
2.hasNext():如果仍有元素可以迭代,则返回true
使用步骤:
1.根据集合对象获取其对象的迭代器对象
2.判断迭代器中是否有元素
3.如果有就获取元素
注意:
列表迭代器是List体系特有的遍历方式,可以在对集合遍历的同时进行添加、删除等操作,但是
必须通过调用列表迭代器的方法来实现
总结:
普通的迭代器在遍历集合的同时不能添加或者删除元素,否则会报:并发修改异常。列表迭代器在遍历集合的同时可以修改集合中的元素,必使使用列表迭代器中的方法。
package cn.itcast.demo8;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class Test {
public static void main(String[] args) {
List list = new ArrayList();
list.add("a");
list.add("b");
list.add("c");
Iterator it = list.iterator();
while (it.hasNext()){
String s = (String) it.next();
if ("b".equals(s)){ //这样写可以规避空指针异常
// list.add("java"); 这样写不行,会报ConcurrentModificationException(并发修改异常)
}
System.out.println(s);
}
System.out.println("------------------");
}
}
package cn.itcast.demo8;
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
public class Test1 {
public static void main(String[] args) {
List list = new ArrayList();
list.add("a");
list.add("b");
list.add("c");
ListIterator lit = list.listIterator();
while (lit.hasNext()){
String s = (String)lit.next();
if ("b".equals(s)){
lit.add("java");
}
System.out.println(s);
}
System.out.println("-----------------");
System.out.println(list);
}
}
泛型简介
什么是泛型
即泛指任意类型,又叫参数化类型,对具体类型的使用起到辅助作用,类似于方法的参数
集合类泛型的解释
表示该集合中存放指定类型的元素
泛型的好处
类型安全、避免了类型转换
总结
泛型一般只和集合类结合使用
泛型是JDK5的新特性,从JDK7开始,后面的泛型可以不用写具体的数据类型了(菱形泛型)
package cn.itcast.demo8;
import java.util.ArrayList;
import java.util.List;
public class Test {
public static void main(String[] args) {
//不使用泛型的集合
List list1 = new ArrayList();
list1.add("a");
list1.add("b");
list1.add("c");
// list1.add(10); //会报类型转换报错
for (Object o : list1){
String s = (String)o;
System.out.println(s);
}
System.out.println("---------------------");
List< String > list2 = new ArrayList< String >();
list2.add("abc");
list2.add("bcd");
list2.add("cde");
for (String s : list2) {
System.out.println(s);
}
}
}
Collections工具类的使用
简介:
针对集合进行操作的工具类
成员方法:
sort(List < T >)——根据元素的自然顺序,将指定列表按升序排序
max(Collections< T >)——返回集合的最大元素
reverse(List < T >)——反转List集合元素
shuffle(List < T >)——使用默认的随机源随即置换指定的列表
来源:CSDN
作者:cheng_09
链接:https://blog.csdn.net/cheng_09/article/details/104263585