9.JAVA面向对象之接口、API

一、接口interface关键字

1.1概述

Java里面由于不允许多重继承,所以如果要实现多个类的功能,则可以通过实现多个接口来实现。

Java接口和Java抽象类代表的就是抽象类型,就是我们需要提出的抽象层的具体表现。OOP面向对象的编程,如果要提高程序的复用率,增加程序的可维护性,可扩展性,就必须是面向接口的编程,面向抽象的编程,正确地使用接口、抽象类这些太有用的抽象类型做为java结构层次上的顶层。

interface 接口名{  代码…  }

1.2特点

1、 通过interface关键字创建接口

2、 通过implements让子类来实现

3、 接口是一个特殊的抽象类,接口里的方法都是抽象方法。

4、 接口突破了java单继承的局限性,可以多继承,多实现。

5、 接口和类之间可以多实现,接口和接口之间可以多继承

6、 接口是对外暴露的规则,是一套开发规范

7、 接口提高了程序的功能扩展,降低了耦合性

8、接口和抽象类都不能new,接口里面是没有构造方法的,接口里面没有成员变量,都是常量。

接口里面可以有抽象方法,普通方法,仅支持default和static(jdk1.8提供的新语法)。

package cn.tedu.oop;
//测试 接口
public class Test1 {
	public static void main(String[] args) {
//		new fu();//接口不能new 抽象类也不行
		fu f = new zi();
		f.eat();
		f.show();
	}

}
interface fu{
	public abstract void eat();
	public abstract void show();
	public static final int AGE = 10;
	
}
class zi implements fu{
	@Override
	public void eat() {
		System.out.println("吃东西");
	}
	@Override
	public void show() {
		System.out.println("做节目");
	}
}
package cn.tedu.oop;
//测试  接口的使用,成员变量,构造方法,普通方法,静态
public class Test2 {
	public static void main(String[] args) {
		A a = new B();
		a.show();
		System.out.println(A.NAME);
	}
}
interface A{
//	public A() {
//		//接口中不能有构造方法
//	}
//	int age ;//接口中不能有成员变量
	public static final String NAME = "王林";//接口中可以有静态不可改的常量
	void show();//抽象方法
//	abstract public void show();//抽象方法的全写和简写
	static void demo() {
		System.out.println("普通方法");//仅支持default和static
	}
}
class B implements A{
	@Override
	public void show() {
		System.out.println("重写父类show");
	}
}
package cn.tedu.oop;
//接口的复杂用法
public class Test3 {
	public static void main(String[] args) {		
	}
}
interface C{
	public abstract void save();//抽象方法
}
interface C1{
	void get(int id);
}
//接口突破java单继承的局限性,接口间发生
interface C2 extends C,C1{
	void del();
}
//实现类可以在继承的同时多实现,实现类必须重写所有的抽象方法,否则是一个抽象类
class C4 extends Object implements C,C1{

	@Override
	public void get(int id) {				
	}
	@Override
	public void save() {	
	}
}
//实现类和接口是  实现关系,  可以多实现
//必须重写  所有抽象方法  否则就是一个抽象类
class C3 implements C,C1,C2{
	@Override
	public void save() {
		System.out.println("保存");
	}
	@Override
	public void get(int id) {
		System.out.println("获取");
	}
	@Override
	public void del() {
		System.out.println("删除");
	}
}

1.3总结

1、 类与类的关系:

-- 是继承关系,java只支持单继承 class A extends B

2、 类和接口的关系:

   --  实现关系 class x  implements A

            -- 类需要把A接口里的所有抽象方法重写

--   多实现 class x implements A,B

              -- 类需要把A,B接口里的所有抽象方法重写

--   可以在继承的同时多实现,注意要先继承后实现

//A是类,B也是类,C和D是接口

class A extends B implements C,D{

3、 接口和接口的关系:

       --  继承关系 interface c extends A

       --  多继承  interface c extends A,B

二、API

2.1Object

2.1.1常用方法

boolean equals(Object obj)    指示其他某个对象是否与此对象“相等”。

使用==进行比较

==比基本类型,直接比较值本身

==比引用类型,直接比较地址值,如果new过,则地址值不同。

 int hashCode()       返回该对象的哈希码值。

 String toString()        返回该对象的字符串表示。

package cn.tedu.api;
//测试  Object工具类
public class Test1 {
	public static void main(String[] args) {
		Object o = new Object();//触发无参构造
		//返回该对象的字符串表示
		System.out.println(o.toString());//展示地址值java.lang.Object@60f82f98
		//指示其他某个对象是否与此对象“相等”
		System.out.println(o.equals("jack"));
		//返回该对象的哈希码值
		System.out.println(o.hashCode());//1626877848
	}
}

创建Student类

package cn.tedu.api;
public class Student {
	private int age;
	private String name;
	public Student() {
		System.out.println("无参构造");
	}
	public Student(String name,int age) {
		//给成员变量赋值
		this.age = age;
		this.name = name;
		System.out.println("含参构造");
	}
	public int getAge() {
		return age;
	}	
	@Override
	public String toString() {
		return "Student [age=" + age + ", name=" + name + "]";
	}
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Student other = (Student) 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;
	}
	//	public void setAge(int age) {
//		this.age = age;
//	}
	public String getName() {
		return name;
	}
//	public void setName(String name) {
//		this.name = name;
//	}	
}

2.1.2Object的复杂用法

package cn.tedu.api;
//测试 api中 Object工具类的复杂用法
public class Test2 {
	public static void main(String[] args) {
		Student s = new Student("王林",24);
		System.out.println(s);
		Student s1 = new Student("王林",24);
		System.out.println(s.equals(s1));
	}
}

2.2String

2.2.1常用方法

length()返回此字符串的长度。

charAt()根据下标获取对应的字符。

lastIndexOf()返回指定子字符串在此字符串中最后一次出现处的索引,从指定的索引开始反向搜索

substring()返回一个新的字符串,它是此字符串的一个子字符串。

equals()将此字符串与指定的对象比较。

startsWith()测试此字符串是否以指定的前缀开始。

endsWith()测试此字符串是否以指定的后缀结束。

split()根据给定正则表达式的匹配拆分此字符串。

trim() 去除字符串两端的空格。

package cn.tedu.api;
import java.util.Arrays;

//测试  String 工具类
public class Test3 {
	public static void main(String[] args) {
		String s = new String();//触发无参构造
		System.out.println(s);
		char [] value =  {'h','E','l','L','o'};
		String s2 = new String(value);//触发含参构造
		System.out.println(s2);
		//char  cahrAt(int index)//根据下标获取对应的字符O
		System.out.println(s2.charAt(4));
		//String concat(String str)//拼接字符串
		System.out.println(s2.concat("123"));
		//boolean endsWith(String suffix)//判断s2是否以”lo“结尾
		System.out.println(s2.endsWith("lo"));
		//boolean contains(CharSequence s)此字符串包含指定的 char 值序列时,返回 true
		System.out.println(s2.contains("he")); 		
		//       boolean equals(Object anObject)//将此字符串与指定的对象比较
		System.out.println(s2.equals("hElLo"));
		//		 int hashCode() //返回此字符串的哈希码
		System.out.println(s2.hashCode());
		//		 int indexOf(String str)子字符串在此字符串中第一次出现处的索引。
		System.out.println(s2.indexOf("l"));
		//		 int lastIndexOf(String str) 子字符串在此字符串中最右边出现处的索引。
		System.out.println(s2.lastIndexOf("o"));
		//		 boolean isEmpty()  //当且仅当 length() 为 0 时返回 true。
		System.out.println(s2.isEmpty());
		//		 int length()//返回此字符串的长度。
		System.out.println(s2.length());
		//		 boolean matches(String regex) 此字符串是否匹配
		System.out.println(s2.matches("he"));
		//		 String replace(char oldChar, char newChar)
		//它是通过用 newChar 替换此字符串中出现的所有 oldChar 得到的。
		System.out.println(s2.replace("h", "demo"));
		//		 boolean startsWith(String prefix) 此字符串是否以指定的前缀开始。
		System.out.println(s2.startsWith("h"));
		//String substring(int beginIndex) 从4索引开始截取子串
		System.out.println(s2.substring(4));
		//String substring(int beginIndex, int endIndex)
		//从索引1开始,到4结束截取子串[0,4)-含头不含尾
		System.out.println(s2.substring(0, 4));
		//		 String toLowerCase()  将此 String 中的所有字符都转换为小写。
		System.out.println(s2.toLowerCase());
		//		 String toUpperCase() 将此 String 中的所有字符都转换为大写。
		System.out.println(s2.toUpperCase());
		//		 String trim()  去掉多余空格
		System.out.println(s2.trim());
		//		 static String valueOf(double d) 把其他类型转成String类型
		System.out.println(s2.valueOf(1.2));
		//		 byte[] getBytes() 把每个字符对应的数字存入btye[]
		byte[] bs = s2.getBytes();
		System.out.println(Arrays.toString(bs));
		//		 String[] split(String regex) 按照规则切割字符串
		String [] ss = s2.split(" ");
		System.out.println(Arrays.toString(ss));
		//		 char[] toCharArray()  把字符串里的字符,存入char[]
		System.out.println(Arrays.toString(s2.toCharArray()));
		
		
		String m = "abcdefghjklmn";
		//变成char[],再遍历char[]
		char [] n = m.toCharArray();
		for(int i=0;i<n.length;i++) {
			System.out.print(n[i]+" ");
		}
		System.out.println();
		//变成byte[] ,再遍历byte[]
		byte [] m1 = m.getBytes();
		for(int i=0;i<m1.length;i++) {
			byte da =m1[i];
			char n1 = (char)da;
			System.out.print(n1+" ");
		}
		System.out.println();
		//直接遍历字符串,获取里面的字符
		for(int i=0;i<m.length();i++) {
			char da = m.charAt(i);
			System.out.print(da+" ");
		}
	}
}

2.3StringBuilder/StringBuffer用来解决字符串拼接的

2.3.1特点

1、  封装了char[]数组

2、  是可变的字符序列

3、  提供了一组可以对字符内容修改的方法

4、  常用append()来代替字符串做字符串连接

5、  内部字符数组默认初始容量是16:initial capacity of 16 characters

6、  如果大于16会尝试将扩容,新数组大小原来的变成2倍+2,容量如果还不够,直接扩充到需要的容量大小。int newCapacity = value.length * 2 + 2;

7、  StringBuffer 1.0出道线程安全,StringBuilder1.5出道线程不安全

package cn.tedu.api;
//测试  StringBuilder/StringBuffer
public class Test1 {
	public static void main(String[] args) {
//		method();//用+拼接
		method1();//
	}
	private static void method1() {
		StringBuilder sb = new StringBuilder();
		String a = "abcd123";
		long start = System.currentTimeMillis();
		for(int i=0;i<100000;i++) {
			sb.append(a);
		}
		long end = System.currentTimeMillis();
		System.out.println(end-start+"毫秒");				
	}
	private static void method() {
		String a = "abcd123";
		String res = "";
		long start = System.currentTimeMillis();
		for(int i=0;i<1000;i++) {
			res = res+a;
		}
		long end = System.currentTimeMillis();
		System.out.println(end-start+"毫秒");		
	}
}

2.4日期类Date

2.4.1概述

存在于java.util.Date包。

用来封装一个毫秒值表示一个精确的时间点。

从1970-1-1  0点开始的毫秒值。

2.4.2常用方法

package cn.tedu.api;
//测试  date工具类
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Scanner;

//date用来获取时间的年月日时分秒毫秒
//SimpleDateFormat--用来把String 类型的日期和date类型的日期互转
public class Test2 {
	public static void main(String[] args) throws Exception  {
//		method();//date
		method1();//string->date
	}
	private static void method1() throws Exception  {
		System.out.println("请输入用户出生日期");
		String b = new Scanner(System.in).nextLine();
		SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd");
		Date d = sf.parse(b);
		long start = d.getTime();//获取出生时间
		long end = System.currentTimeMillis();//获取当前时间
		System.out.println((end-start)/1000/60/60/24/365);	
	}
	private static void method() {
		Date d = new Date();//使用当前时间
		System.out.println(d.getTime());//返回1970.1.1零点的毫秒值
		System.out.println(d.getYear());//从1900年开始算
		System.out.println(d.getDate());//今天是几号
		System.out.println(d.getDay());//今天礼拜几
		System.out.println(d.getMinutes());//获取分钟
		System.out.println(d.getMonth());//获取月份
		System.out.println(d.toLocaleString());	//变成当前时间	
	}
}

2.5日期工具SimpleDateFormat

2.5.1概述

日期格式化工具,可以把Date对象格式化成字符串,也可以日期字符串解析成Date对象。

2.5.2常用方法(代码在上面2.4里面)

format(Date):把Date格式化成字符串

parse(String):把String解析成Date

2.6BigDecimal/BigInteger

2.6.1概述

BigDecimal:专门解决小数运算不精确的问题。

BigInteger:常用来解决超大的整数运算。

2.6.2常用方法

add(BigDecimal bd): 做加法运算

substract(BigDecimal bd) : 做减法运算

multiply(BigDecimal bd) : 做乘法运算

divide(BigDecimal bd) : 做除法运算

divide(BigDecimal bd,保留位数,舍入方式):除不尽时使用

setScale(保留位数,舍入方式):同上

pow(int n):求数据的几次幂

package cn.tedu.api;
import java.math.BigDecimal;
import java.util.Scanner;
//测试  bigdecimal工具类
public class Test3 {
	public static void main(String[] args) {
//		method();
		method1();
	}
	private static void method1() {
		System.out.println("请输入第一个小数");
		double a = new Scanner(System.in).nextDouble();
		System.out.println("请输入第二个小数");
		double b = new Scanner(System.in).nextDouble();
		//方式1:BigDecimal(double val),有坑不能用
		//解决运算不精确
//		BigDecimal bd = new BigDecimal(a);
//		BigDecimal bd1 = new BigDecimal(b);
		//方式2:推荐使用BigDecimal(String val)
		//把参数,从double-->String----1.String.valueOf()----2.+""
		BigDecimal bd = new BigDecimal(String.valueOf(a));
		BigDecimal bd1 = new BigDecimal(b+"");
		//调用方法
		//加法
		System.out.println(bd.add(bd1));
		//减法
		System.out.println(bd.subtract(bd1));
		//乘法
		System.out.println(bd.multiply(bd1));
		//除法  java.lang.ArithmeticException除不尽bug
		System.out.println(bd.divide(bd1,2,BigDecimal.ROUND_HALF_UP));
	}

	private static void method() {
		System.out.println("请输入第一个小数");
		double a = new Scanner(System.in).nextDouble();
		System.out.println("请输入第二个小数");
		double b = new Scanner(System.in).nextDouble();
		System.out.println(a+b);//不精确
		System.out.println(a-b);//不精确
		System.out.println(a*b);//不精确
		System.out.println(a/b);//不精确
	}
}

2.7包装类

父类:Number数字包装类的抽象父类(前6个)。

package cn.tedu.api;
//测试  Integer 包装类
public class Test4 {
	public static void main(String[] args) {
		//创建对象---把基本类型  变成  包装类型
		Integer i = new Integer(5);
		//调用intvalue方法
		System.out.println(i.intValue());//把包装类型  变成  基本类型
		//调用parseInt方法静态的
		System.out.println(Integer.parseInt("5"));//把字符串转成基本类型
		//调用valueOf方法静态的
		System.out.println(Integer.valueOf(5));//把基本类型转成包装类型
		
		Double d = new Double(2.3);//把double基本类型  变成  包装类型
		Double d1 =Double.valueOf(d);
		System.out.println(d.doubleValue());//包装类型变成基本类型
		
	}

}

三、拓展

3.1抽象类abstract的注意事项

抽象方法要求子类继承后必须重写。那么,abstract关键字不可以和哪些关键字一起使用呢?以下关键字,在抽象类中。用是可以用的,只是没有意义了。

1、 private:被私有化后,子类无法重写,与abstract相违背。

2、 static:静态的,优先于对象存在。抽象方法需要子类重写,而静态的方法是无法被重写的,因此二者是矛盾的。

3、 final:被final修饰后,无法重写,与abstract相违背。

3.2接口和抽象类的区别

1、抽象类和接口都不能直接实例化,如果要实例化,抽象类变量必须指向实现所有抽象方法的子类对象,接口变量必须指向实现所有接口方法的类对象。

2、抽象类要被子类继承,接口要被类实现。

3、接口只能做方法申明,抽象类中可以做方法申明,也可以做方法实现

4、接口里定义的变量只能是公共的静态的常量,抽象类中的变量是普通变量。

5、抽象类里的抽象方法必须全部被子类所实现,如果子类不能全部实现父类抽象方法,那么该子类只能是抽象类。同样,一个实现接口的时候,如不能全部实现接口方法,那么该类也只能为抽象类。

6、抽象方法只能申明,不能实现,接口是设计的结果 ,抽象类是重构的结果

7、抽象类里可以没有抽象方法,如果要扩展抽象类的新方法,子类将很容易的就能得到这些新方法。

8、如果一个类里有抽象方法,那么这个类只能是抽象类

9、抽象方法要被实现,所以不能是静态的,也不能是私有的。

10、接口可继承接口,并可多继承接口,但类只能单根继承。

3.3了解软件设计的开闭原则OCP

开放功能扩展,关闭源码修改。等

开闭原则的英文全称是Open Close Principle,缩写是OCP,它是Java世界里最基础的设计原则,它指导我们如何建立一个稳定的、灵活的系统。

开闭原则的定义是:软件中的对象(类、模块、函数等)应该对于扩展是开放的,但是对于修改是封闭的。

开闭原则,是一种设计模式,随着面向对象程序设计的思想,应运而生。

开,指的是可以在源代码的基础上进行扩展,比如继承,接口,抽象类等。在JAVA中,之所以用继承,是在可以直接调用类库的前提下,对其功能进行扩展。不需要应用者去了解封装类的内部逻辑就可以做开发。

闭:指不允许对原有的代码进行修改。以免影响其他现有功能,造成功能瘫痪。

3.4StringBuilder和StringBuffer的区别

1、 在线程安全上,

--StringBuffer是旧版本就提供的,线程安全的。@since   JDK1.0

--StringBuilder是jdk1.5后产生,线程不安全的。@since       1.5

2、 在执行效率上,StringBuilder > StringBuffer > String

3、 源码体现:本质上都是在调用父类抽象类AbstractStringBuilder来干活,只不过Buffer把代码加了同步关键字,使得程序可以保证线程安全问题。

abstract class AbstractStringBuilder implements Appendable, CharSequence {

 

 3.5自动装箱和自动拆箱

自动装箱:把基本类型包装成一包装类的对象

Integer a = 5;//a是引用类型,引用了包装对象的地址。

编译器会完成对象的自动装箱:Integer a = Integer.valueOf(5);

自动拆箱:从包装对象中,自动取出基本类型值

    int i = a;//a现在是包装类型,没法给变量赋值,需要把5取出来。

编译器会完成自动拆箱:int i = a.intValue();

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

太彧

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值