1.作业
2.面向对象补充(匿名对象,内部类,代码块,向下转型)
3.API
4.Object类
5.String类
重写和重载的区别
重载 重写 位置 当前类中,对自己方法的重载 有子父类,子类重写父类方法 访问修饰符 没要求 与父类一样(大于等于) 返回值类型 没要求 与父类一样 方法名 与被重载的一样 与父类一样 参数列表 不一样 与父类一样 方法体 不一样 不一样 抽象和接口的区别
抽象 接口 类 类 不是类 子类 继承(extends)抽象类 子类实现(implements)接口 属性 正常属性 没有属性,全都是静态常量 方法 有正常方法,有抽象方法 全都是抽象方法 构造方法 有 没有 接口文件的特点(至少3个)
- 不是类
- 没有属性
- 没有正常方法
- 没有构造方法
- 子类可以实现多个接口
- 接口继承接口,且允许多继承
多态的形成前提条件
- 继承/实现
- 重写方法
- 向上转型
- 方法的参数列表是父类,传参数给子类
- 方法的返回值类型是父类,return子类对象
- 数组的类型是父类,存储的是子类对象
多态相关代码运行口诀: 编译看父类,运行看子类
详见项目day11
public class TestOOP1 {
public static void main(String[] args) {
// 创建对象
// 类名 对象名 = new 构造方法();
Student s = new Student(18,"老王");
// s就是对象名,通过名字调用对象的方法
String name = s.getName( );
System.out.println(name );
int age = s.getAge( );
System.out.println(age );
// -------------
// 所谓匿名对象,就是名字
int a = new Student(19, "老李").getAge( );
System.out.println(a );
String n = new Student(19, "老李").getName( );
System.out.println(n );
// --------------
Student student = new Student( );
show(student);
// 总结: 在使用一次对象的时候,匿名对象会简单方便一点
show(new Student( ));
}
public static void show(Student s) {
System.out.println(s );
}
}
内部类,就是在类里面再定义一个类
匿名内部类简化以前继承父类,实现父接口的过程
// 父抽象类
public abstract class Animal {
public abstract void eat();
}
// 父接口
public interface USB {
void work();
}
// 测试匿名内部类
public class TestOOP2 {
public static void main(String[] args) {
Dog dog = new Dog( );
dog.eat();
/** 以前搞出一个父类的子类对象需要:
* 1 创建子类文件
* 2 继承父类
* 3 重写方法
* 4 创建子类对象
* -----------------
* 使用匿名内部类可以简化实现父类的过程
*/
// 这就是匿名内部类
// 相当于是一个子类继承了父类,并重写了方法
new Animal(){
@Override
public void eat() {
System.out.println("猫吃鱼" );
}
}.eat();// 子类还调用了方法
// 匿名内部类完成 继承父抽象类
new Animal(){
@Override
public void eat() {
System.out.println("猪吃白菜" );
}
}.eat();
// ==================
show(dog);// 没用匿名内部类以前
// 用来匿名内部类
show(new Animal(){
@Override
public void eat() {
System.out.println("老虎吃其他小动物" );
}
});
// ------------------
// 匿名内部类实现接口
new USB(){
@Override
public void work() {
System.out.println("U盘工作" );
}
};
}
public static void show(Animal animal){
animal.eat();
}
}
代码块就是一块使用**{}**包裹的代码,可以理解为类中的一个代码片段(部分代码)
- 构造代码块
- 静态代码块
- 局部代码块
构造代码块:
- 位置: 类中方法外
- 写法: {}
- 作用: 随着构造方法执行先执行
package com.qf.oop;
/**
* |-----------------------------------------------
* | ____ _ _____ _ _ _ |
* | / __ \ (_) / ____|| | (_)(_) |
* || | | | _ _ _ | (___ | |__ _ _ _ _ |
* || | | || || | | | \___ \ | '_ \ | || || | | ||
* || |__| || || |_| | ____) || | | || || || |_| ||
* | \___\_\|_| \__,_||_____/ |_| |_||_|| | \__,_||
* | _/ | |
* | |__/ |
* |-----------------------------------------------
* | 天道酬勤 |
* | 代码敲烂 月薪过万 |
* L----------------------------------------------
*
* @desc
*/
public class Student {
private int age;
private String name;
// 构造代码块
{
System.out.println("构造代码块执行了" );
this.age = 1;
this.name = "张三";
}
public Student() {
System.out.println("Student无参构造执行了" );
}
// ... 省略
}
public static void main(String[] args) {
/**
* --- 演示构造代码块 ---
* 每次构造方法执行前先执行构造代码块
*/
Student student = new Student( );
System.out.println("-------------" );
System.out.println(student.getAge() );
System.out.println(student.getName() );
System.out.println("--------------" );
Student s2 = new Student(2, "老王");
System.out.println(s2.getName() );
System.out.println(s2.getAge() );
}
静态代码块
- 位置: 类中方法外
- 写法: static {}
- 作用: 随着类加载而执行,其中的代码在内存只有一份
- 常用于初始化一些 特殊代码运行环境(jdbc环境)
public class Student {
private int age;
private String name;
// 静态代码块
static {
System.out.println("静态代码块" );
}
// 省略
}
局部代码块
- 位置: 写在方法中
- 写法: {}
- 作用: 在方法内单独开辟个区域,定义的代码可以提前释放
// 普通方法
public void show(){
int a = 1;
// 局部代码块
System.out.println(a );
{
int b = 2;
System.out.println(a );
System.out.println(b );
// 局部代码块执行完就消失了
}
int b = 3;// 这个b与上面的b不冲突
System.out.println(a );
System.out.println(b );
}
- 向上转型: 将子类对象赋值给父类引用(将子类包装成父类)
- 向下转型: 将父类赋值给子类对象(将包装后的父类再变回到子类)
- 先有向上转型才能向下转型
- 作用
- 为了调用子类特有的方法(父类没有该方法)
public static void main(String[] args) {
// - 向上转型: 将子类对象赋值给父类引用(将子类包装成父类)
// - 向下转型: 将父类赋值给子类对象(将包装后的父类再变回到子类)
// - 先有向上转型才能向下转型
// Animal animal = new Dog();// 向上转型
// Dog dog = (Dog) animal;// 向下转型
// dog.eat();
// 没有向上转型,直接向下,会报错ClassCastException
// 类转换异常
// Animal animal = new Animal( );
// Dog dog = (Dog) animal;
// dog.eat();
// 向上转型,向下强制转型(类型不对应也不能向下)
// 报错
// Animal animal = new Cat();
// Dog dog = (Dog) animal;
/**
* 为什么要转型?
* 因为向上之后,这个父类引用能调用的方法只能是子父类都有的方法
* 如果此时需要调用子类特有方法,就不行
*/
Animal animal = new Dog();// 向上转型
animal.eat();
// 父类不能调用子类特有方法
// animal.watchHome();
// 此时就需要向下转型
Dog dog = (Dog) animal;
dog.watchHome();
}
面向对象
- 类,对象,属性,方法,内存关系
- 构造方法,重载,this
- 封装,继承,this和super,重写
- 访问修饰符,多态
- staic,final
- 抽象和接口
利用面向对象的思想,去学习其他的类(常用类)
- Object,String,包装类
- 日期类,Math,随机数
- 异常类
- 集合
- IO
- 多线程
API : Application Programimg Interface (应用程序编程接口)
- 它就是java文件的说明书
- 通过api学的关于类/接口
- 所在包
- 继承哪些类,实现哪些接口
- 关于类/接口详细说明
- 类中属性的说明
- 类中构造方法的说明
- 类中方法的说明
Object是所有类的父类,每个类都直接或者间接继承自Object
Object类有一个无参构造,可以创建对象
// 创建Object类 Object o = new Object( );
Object类中有很多方法,学习的
- hashcode(了解)
- equals和toString(重要)
返回对象的hash值(哈希值),即认为是对象的地址值
Object o = new Object( );
System.out.println(o );
System.out.println(o.hashCode() );
Dog dog1 = new Dog( );
System.out.println(dog1.hashCode() );
Object 类中的equals 判断两个对象是否相等(判断地址值)
- boolean equals (Object obj)
public class Student{
// 部分代码省略
/**
* 重写equals 用于判断对象属性是否一致
*/
@Override
public boolean equals(Object obj){// Obj obj = s2
Student other = (Student) obj;
if (this.age == other.getAge() && this.name.equals(other.getName())){
return true;
}
return false;
}
}
public static void main(String[] args) {
// Dog类继承自Object,调用父类的方法
Dog dog = new Dog( );
dog.equals(null);
// 创建Object类
Object o = new Object( );
System.out.println(o );
// 演示hashcode
System.out.println(o.hashCode() );
Dog dog1 = new Dog( );
System.out.println(dog1.hashCode() );
// ===================
// 演示equals
Object o1 = new Object( );
Object o2 = new Object( );
/**
* 发现Object类中equals方法使用 == 判断两个地址是否相同
* 但是,每次new都会创建新对象(新地址)
* 即基本上比较其他对象都会是false
*/
boolean equals = o1.equals(o2);
System.out.println(equals);
Student s1 = new Student(18,"宏伟");
Student s2 = new Student(19,"宏伟" );
/**
* 但是大部分时候,在开发时
* 都会认为属性完全一样的两个对象,是相等的
* 所以一般情况,基本所以子类都会重写equals方法,判断对象属性是否一样
*/
System.out.println(s1.equals(s2) );
}
总结:
- 以后每个类都要重写equals来判断对象的属性是否相等,而不能直接用object类中的equals判断地址值,因为无意义
Object类中的toString是将对象信息返回
- 内部是将对象类路径拼接@,拼接地址值返回的
- 这样无意义,子类都会重写
public class Student {
private int age;
private String name;
// 省略了部分代码....
// 重写toString,返回类的属性信息
public String toString(){
return "Student = {age = "+age+",name = "+name+"}";
}
}
public static void main(String[] args){
Object o3 = new Object( );
/**
* 以前直接在输出语句输出对象,其实就已经在默认调用toString()方法
*/
System.out.println(o3 );
System.out.println(o3.toString( ) );
/**
* 输出对象地址值没什么实际作用
* 经常用的是: 打印对象属性值
* 所以: 每个子类都重写toString,返回类的属性信息
*/
Student s3 = new Student(18,"宏伟");
System.out.println(s3 );
}
}
总结:
- 以后每个子类都重写toString() 返回对象的属性信息
String是一个类,代表字符串
程序中任何字符串都是String类的对象
String是常量,创建出的字符串不能更改
public static void main(String[] args) {
String a = "abc";
// 这里a就是String类的对象
// 对象可以调用方法
int length = a.length( );
System.out.println(length );
// 字符串不能更改
// 以下代码只是将a变量重新指向新的字符串对象
// 原来的对象"abc"并没变化
a = "java";
}
String类提供很多操作字符串的方法
- 提供了各种可以创建字符串的构造方法
- 查找字符串,拆分字符串,截取字符串,判断,转换
空参构造
通过字节数组创建字符串对象
/**
* 演示构造方法
*/
public static void show2(){
// 空参构造,创建空字符串
String s = new String( );
// 一般不用,建议用下方这样创建空字符串
String s2 = "";
System.out.println(s);
// 场景: 一般用于数据传输(IO流,Socket网络传输)
byte[] bytes = {65,66,67,68};
String s1 = new String(bytes);
System.out.println(s1 );
}
/**
* 演示常用的字符串的方法
*/
public static void show3(){
/**
* 查找字符串
*/
String s = "java";
// 根据下标找字符(从0开始)
char c = s.charAt(0);
System.out.println(c );
// 根据字符串(字符)找下标'
// 找不到返回-1
int i1 = s.indexOf('j');
int i2 = s.indexOf("cv");
System.out.println(i1 );
System.out.println(i2 );
// 从后向前找对应字符的下标
int a = s.lastIndexOf("a");
System.out.println(a );
/**
* 拆分字符串
*/
String s2 = "CN-ZZ-20231023-1";
// 按照格式拆分
String[] split = s2.split("-");
System.out.println(Arrays.toString(split ) );
System.out.println(split[2] );
/**
* 截取字符串
*/
String s3 = "410123200001010567";
// 截取出生日(指定开始,默认截取到末尾)
String substring = s3.substring(6);
// 截取出生日(指定开始(包含),末尾(不包含))
String substring2 = s3.substring(6,14);
System.out.println(substring2 );
/**
* 判断字符串是否替换,包含,相等
*/
String s4 = "我爱赌博";// 不要学习,纯属节目效果
// 替换
String replace = s4.replace("赌博", "**");
System.out.println(replace);
// 判断是否包含
boolean contains = s4.contains("赌");
System.out.println(contains );
// 判断相等
String name1 = "WBG";
String name2 = "wbg";
System.out.println(name1.equals(name2) );
// 忽略大小写判断是否相等
boolean b = name1.equalsIgnoreCase(name2);
System.out.println(b );
/**
* 获得字符串长度
*/
String s5 = "JDG";
int length = s5.length( );
System.out.println(length );
/**
* static String valueOf(参数)
* 将大部分数据类型都转成String
*/
String s6 = String.valueOf(1);
String s7 = String.valueOf(true);
String s8 = String.valueOf(1.1);
String s9 = String.valueOf(new Student( ));
}
上午的作业再写一遍(不要抄,看着文档写)
面向对象补充部分,掌握(匿名内部类,向下转型)
Object类(equals和toString)
String需要记住特性,记住方法以及功能(抄本上,再敲2遍)