继承与多态
extends
- 如果父类中没有无参构造方法只有有参的子类在调用的过程中无法直接调用会报错
there is no default constructor available in
这个时候可以在父类增加一个构造方法,或者可以在子类构建方法来解决。
public test(int a,int b)
{
super(a,b);
}
-
this(a,a)
等可以直接对成员变量赋值 -
super():父类的构造
-
直接调用成员时调用的就是本类的(子类)的成员,用super来访问父成员;子类可以覆盖父类的
-
instanceof
:判断前面的是不是后面的对象的实例;返回true或false;子类对象也是父类的实例,但反之false; -
上转型对象:父类类型的变量是可以指向子类对象的;如a是b的父类的话
a a1; a1=new b(a,b,c);
是可以的,但不可以调用扩展的属性和方法(子类独有的方法),上传型对象在调用覆盖的方法(父类子类都有的方法)时表现出来的是子类的特征。
-
多态:上转型对象调用子类覆盖的方法(属性)时会具体调用具体绑定的那个子类中的那个方法(属性)。
-
上转型对象是可以强制转型的。
Father father1=new Chlid();
Child child1=(Child) father1;
- object是所有类的父类。
- 重写方法
@Override//在方法中添加这个;
public String toString() {
return "core的"+a;
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nr3CcVT6-1665733965854)(C:/Users/86186/AppData/Roaming/Typora/typora-user-images/image-20220927115535523.png)]
-
抽象类作用:
可以进行子类继承,概括着子类公有的方法把所有子类的抽象方法搞到抽象类中的定义。
-
接口:其实接口也是类,把
class
改成interface
就是接口形式
public interface Shape {
public double length();
public double area();
}
接口里的方法其实都是抽象方法,然后使用类来实现接口
public class Triangle implements Shape {}
在主函数中可以直接像使用抽象类一样使用接口
import java.util.Scanner;
import java.util.Objects;
public class Main {
public static void main(String[] args) {
//接口类shape和他的3个实现类
Shape shape;
shape =new Triangle(3,4,5);
System.out.println(shape.length());
System.out.println(shape.area());
shape=new Rect(2,3);
System.out.println(shape.length());
System.out.println(shape.area());
shape =new Circle(2);
System.out.println(shape.length());
System.out.println(shape.area());
}
}
接口还是编译成class,借口就是个类啊、抽象类完成的事情接口都可以做但是他更加灵活
接口之间可以继承多个,类可以是一个类的子类也可以实现多个接口里的方法 所以说接口更灵活可以实现多个而只能是一个类的子类
接口中的属性前隐藏了 //public static final
接口中的方法前隐藏了//abstract public
然后实现类就相当于这个类继承了各个接口(类)里面的东西;
- 成员类:类也可作为成员;访问时可以
E.F ef=e.new F();//(正确)
E.F ef=new E.F();//(错误)
在编译成文件后;
文件名为:E$F.class
l
匿名内部类:创建接口需要创建一个对象给他起个名而匿名内部类可以不需要定义类来实现这个接口,可以直接用接口俩创建对象后面加{括号里面是接口中的方法}
使用实现类对象可以创建多个类对象但是如果我们是用匿名内部类只能使用一次
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jxKPLKer-1665733965855)(C:/Users/86186/AppData/Roaming/Typora/typora-user-images/image-20220930153617594.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lB2KHPUo-1665733965855)(C:/Users/86186/AppData/Roaming/Typora/typora-user-images/image-20220930153535986.png)]
import java.util.Scanner;
import java.util.Objects;
public class Main {
public static void main(String[] args) {
//抽象类shape和他的3个子类
Shape shape=new Shape() {
@Override
public double length() {
return 0;
}
@Override
public double area() {
return 0;
}
};
}
}//main
try {
int a= reader.nextInt();
int b= reader.nextInt();
int c=a/b;
System.out.println(c);
}
catch (InputMismatchException e)
{
System.out.println("输入类型不匹配");
System.out.println(e.getCause());
System.out.println(e.getMessage());
}
catch (ArithmeticException e)
{
System.out.println(e.getCause());//e.getCause();
System.out.println(e.getMessage());
}
catch (Exception e)//Exception是所有异常的父类会把所有的异常catch住
{
System.out.println("其他异常我全包");
}
如果捕获到异常 try里面的内容就不运行了运行catch里面的内容然后继续运行如果错误无法被捕获就会报错了在try那里那个
finally
:什么时候都能执行到,起到一个收尾的作用
catch有父子类关系的时候子类在前父类在后
可以在错误上用art+enter来添加东西
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KGFqN6Nd-1665733965855)(C:/Users/86186/AppData/Roaming/Typora/typora-user-images/image-20221004104659702.png)]
第一个是添加throws(生命可能抛出的异常)
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class cee {
public static void main(String[] args) throws IOException {
FileInputStream fis=new FileInputStream(".");
fis.close();
}
}
第二种是添加try catch
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class cee {
public static void main(String[] args) {
FileInputStream fis= null;
try {
fis = new FileInputStream(".");
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
}
try {
fis.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
throw
:抛出异常
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class cee {
public static void main(String[] args) {
// FileInputStream fis=new FileInputStream("E:\\c++");
// fis.close();
m1();
}
public static void m1()
{
System.out.println("m1...");
throw new RuntimeException("DDDD");//可以抛出异常
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GgE3MyCk-1665733965856)(C:/Users/86186/AppData/Roaming/Typora/typora-user-images/image-20221004110357644.png)]
而这些错误就相当于一个类可以设计子类
public class gme extends RuntimeException{
int balance;
int getMoney;
public gme(String message, int balance, int getMoney) {
super("余额不足");
this.balance = balance;
this.getMoney = getMoney;
}
}
封装:
我们一般将成员变量设置为private;
在set和get变量时可以使用alt+insert进行直接添加
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mc50SpRo-1665733965856)(C:/Users/86186/AppData/Roaming/Typora/typora-user-images/image-20221004112754239.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VZyj7UsA-1665733965856)(C:/Users/86186/AppData/Roaming/Typora/typora-user-images/image-20221004112828866.png)]
public class student {
private int id;
private String name;
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 void m1()
{
System.out.println("m1...");
}
public student(int id, String name) {
this.id = id;
this.name = name;
}
}
这样可以体现类的封装性
hashcode和equals()
啥也别说了alt+insert;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CzNbygvC-1665733965857)(C:/Users/86186/AppData/Roaming/Typora/typora-user-images/image-20221004114405016.png)]
自动生成了
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Product product = (Product) o;
if (id != product.id) return false;
if (Double.compare(product.price, price) != 0) return false;
return Objects.equals(name, product.name);
}
@Override
public int hashCode() {
int result;
long temp;
result = id;
result = 31 * result + (name != null ? name.hashCode() : 0);
temp = Double.doubleToLongBits(price);
result = 31 * result + (int) (temp ^ (temp >>> 32));
return result;
}
单例模式
就建立一个对象
饿汉单例模式
public class Singleton1 {
private static Singleton1 instance = new Singleton1();
private Singleton1(){}
public static Singleton1 getInstance(){
return instance;
}
类加载的方式是按需加载,且加载一次。。因此,在上述单例类被加载时,就会实例化一个对象并交给自己的引用,供系统使用;而且,由于这个类在整个生命周期中只会被加载一次,因此只会创建一个实例,即能够充分保证单例,这种写法比较简单,就是在类装载的时候就完成实例化。避免了线程同步问题。
懒汉单例模式
public class Singleton2 {
private static Singleton2 instance;
private Singleton2(){}
public static Singleton2 getInstance(){
if (instance == null) {
instance = new Singleton2();
}
return instance;
}
我们从懒汉式单例可以看到,单例实例被延迟加载,即只有在真正使用的时候才会实例化一个对象并交给自己的引用。
这种写法起到了Lazy Loading的效果,但是只能在单线程下使用。如果在多线程下,一个线程进入了if (singleton == null)判断语句块,还未来得及往下执行,另一个线程也通过了这个判断语句,这时便会产生多个实例。所以在多线程环境下不可使用这种方式。
双锁单例模式
public class Singleton {
private volatile static Singleton instance;
private Singleton (){}
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
双锁模式,进行了两次的判断,第一次是为了避免不要的实例,第二次是为了进行同步,避免多线程问题。由于singleton=new Singleton()对象的创建在JVM中可能会进行重排序,在多线程访问下存在风险,使用volatile修饰signleton实例变量有效,解决该问题。
类的反射:
过程
//AA类
//public class AA {
// private int a=1;
// public int b=2;
// private String stuName;
//
//
// private AA()
// {
// System.out.println("AA()...");
// }
//
// private AA(int a)
// {
// this.a=a;
// System.out.println("AA(int)...");
// }
//
// private void m1()
// {
// System.out.println("m1()....");
// }
// public void m1(double x)
// {
// System.out.println("m1(double)....");
// }
//}
//--------------------------------------------------------------------------------
//创建对象
Class<AA> aaClass = AA.class; //得到了A类的字节码 AA.class
// AA aa=new AA();
// Class<AA> aaClass1= (Class<AA>) aa.getClass();
// System.out.println(aaClass1==aaClass);
Constructor<AA> c1 = aaClass.getDeclaredConstructor(null);
c1.setAccessible(true);
AA aa = c1.newInstance();
System.out.println(aa);
Constructor<AA> c2 = aaClass.getDeclaredConstructor(int.class);
c2.setAccessible(true);
AA aa2 = c2.newInstance(10);
System.out.println(aa2);
//为属性a赋值
Field aField = aaClass.getDeclaredField("a");
aField.setAccessible(true);
aField.setInt(aa,100); //aa.a=100;
System.out.println(aField.getInt(aa)); //aa.a
Field bField = aaClass.getField("b");
bField.setInt(aa,10000);
System.out.println(bField.getInt(aa));
//调用成员方法
Method m1Method = aaClass.getDeclaredMethod("m1");
m1Method.setAccessible(true);
m1Method.invoke(aa,null); //aa.m1()
Method m2Method = aaClass.getMethod("m1",double.class);
m2Method.invoke(aa,10000); //aa.m2(444)
枚举类型
//public enum SignalLight {
// RED(1,"red"),GREEN(2,"green"),YELLOW(3,"yellow");
枚举的类型必须在类的最前面
// @Override
// public String toString() {
// return "SignalLight{" +
// "value=" + value +
// ", name='" + name + '\'' +
// '}';
// }
// int value;
// String name;
// SignalLight(int value,String name)
// {
// this.value=value;
// this.name=name;
// }
//
//}
//}
public class Main {
public static void main(String[] args) {
SignalLight light1=SignalLight.RED;
SignalLight light2=SignalLight.GREEN;
SignalLight light3=SignalLight.YELLOW;
System.out.println(light1);
System.out.println(light2);
System.out.println(light3);
SignalLight[] values = SignalLight.values();
for (int i=0; i< values.length;i++)
{
System.out.println(values[i]);
}
//枚举类型不能被实例化
}
}
String类
string类中的equals方法是被重写的equals方法比较字符是否相同
用封装类的.parse方法可以转换
double d=Double.parseDouble("123.345");
StringBuffer类
克服String类的不变性的,在原来字符串的基础上的增删改
public class StringTest {
public static void main(String[] args) {
StringBuffer buffer1=new StringBuffer("abcd");
StringBuffer buf2=buffer1.append("123").delete(1,3);//增加
}
}
Date类
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class Main {
public static void main(String[] args) throws ParseException {
Date date1=new Date();
Date date2=new Date(0);
System.out.println(date1);
System.out.println(date2);
//Date-->String
SimpleDateFormat sdf=new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss:S E");
String strDate1 = sdf.format(date1);
String strDate2 = sdf.format(date2);
System.out.println(strDate1);
System.out.println(strDate2);
// 1970年01月01日 08:00:00:0 星期四 --> 1970-01-01 08:00:00
// String-->Date-->String
SimpleDateFormat sdf1=new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss:S E");
Date date3 = sdf1.parse(strDate2);
SimpleDateFormat sdf2=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String strDate3 = sdf2.format(date3);
System.out.println(strDate3);
//3天之后的时间(300天之后)
long time =new Date().getTime();
System.out.println(time);
Date date4=new Date(time+3*24*60*60*1000);
long time1 = System.currentTimeMillis();
System.out.println(time1);
}
}
Calendar类:
import java.util.Calendar;
import java.util.Date;
public class Main {
public static void main(String[] args) {
Calendar calendar=Calendar.getInstance();//这样get日历类
Date date=calendar.getTime();//得到系统的当前时刻
int dayofyear=calendar.get(Calendar.DAY_OF_YEAR);
System.out.println(dayofyear);
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-igGdSMq5-1665733965857)(C:/Users/86186/AppData/Roaming/Typora/typora-user-images/image-20221014145352593.png)]
Math类
Math.random()
获得一个随机数方法返回值是 [0,1)
如果要取一个[1,10]之间的整数可以int i1= (int)(Math.random()*10+1);
还有那些数学操作
BigInteger类
import java.math.BigInteger;
public class Main {
public static void main(String[] args) {
BigInteger bigA= new BigInteger("123123123123333333333333");
BigInteger bigB=new BigInteger("12");
BigInteger bigC=bigA.add(bigB);
System.out.println(bigC);
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bXXCatrs-1665733965857)(C:/Users/86186/AppData/Roaming/Typora/typora-user-images/image-20221014151527660.png)]
还可以做各种其他的操作
BigDecimal类
解决java在浮点类型时不能准确计算的所以需要BigDecimal类;
在商业运算中,金额运算中需要使用BigDecimal类
Random类
泛型类与集合框架
interface GenericInterface<F>
{
F getF();
}
//泛型接口
class Generic1<T> //T表示的就是一种数据类型,没有置顶//默认就是一个object
{
T t1;
T t2;
public T getT1() {
return t1;
}
public T getT2() {
return t2;
}
}
//上面就是泛型类;
public class Main {
public static void main(String[] args) {
Generic1<Integer> generic1=new Generic1<Integer>();//如果没<>就是object类<添加什么类类型就只能用什么类了>
Generic1<String> generic2=new Generic1<String>();
Generic1 generic3=new Generic1();
System.out.println(generic1.getClass()==generic2.getClass());//true
System.out.println(generic3.getClass()==generic2.getClass());//true
System.out.println(generic1.getClass()==Generic1.class);//true
//在运行时都相等;
}
}