java记录,泛型和接口的使用

接口

接口是抽象类的延伸,可以将接口看作是纯粹的抽象类,接口中的所有方法都没有方法体。接口使用interface关键字进行定义:

public interface MyList{
int size(); 
boolean isEmpty(); 
boolean contains(int o); 
boolean add(int o);
}

接口可以像类一样被权限修饰符修饰,但public关键字仅限用于接口在与其同名的文件中被定义。

一个类实现一个接口可以使用 implement 关键字:

public class MyLinkedList implements MyList{
}

Notice:在接口中定义的方法必须被定义为public 或者 abstract 形式,其他修饰权限不被java编译器认可,接口中不将该方法声明为public形式,方法默认也是public形式。

但是在类中实现接口时,对接口中的方法体进行编写,必须将接口方法声明为public形式,若不加上public则会报错。

补充:在接口中定义的任何字段都自动是staticfinal的。

接口与继承:
java中不允许多重继承,即类的父类只能唯一。但是接口可以实现多重继承,因为一个类可以同时实现多个接口。可以将所有需要继承的接口放置在 implement 关键字后并使用逗号隔开。(可能会产生巨大的代码量,因为必须在类中实现所有接口中的方法)。
格式如下:

class 类名 implements 接口1,接口2,接口3,...,接口 n

注意,接口之间的继承也使用 extends 关键字:

interface intf1{
}
interface intf2 extends intf1{
}

泛型

泛型实际上就是使程序员定义安全的类型。为什么说是定义安全的类型呢。
因为在泛型出现之前,java也提供了对object的引用“任意化”操作,这种“任意化”操作就是对object引用进行向下转型向上转型操作,但某些强制类型转换的错误也许不会被编译器捕捉,而在运行后出现异常,为了消除这种安全隐患,java提供了泛型。

1.在定义泛型类时,可以声明多个定义类型:

class Example<T1,T2>

T1,T2为可能被定义的类型。
这样在该类中实例化对象时,就可以指定多个类型:

Example<Boolean,Double>  exp1 = new Example<Boolean,Double>();

2.定义泛型类时声明数组类型

public class ArrayClass<T>{
private T[] array;
public voidsetArray(T[] array){
	this.array = array;
	}
public T[] getArray(){
	return array;
}
}


public static void main(String[] args){

ArrayClass<Integer> a = new ArrayClass<Integer>();
Integer[] array = {1,2,3};
a.setArray(array);



}

Notice:不可以使用泛型来建立数组的实例:

T[] array = new T[10];

上述代码是错误的。

3.集合类声明容器的元素

泛型的高级用法

泛型的高级用法包括限制泛型可用类型使用类型通配符等。
1.限制泛型可用类型
语法如下:

class 类名 <T extends anyClass>

其中,anyClass 代表某个接口或类。
在使用泛型限制后,泛型类的类型必须实现或继承了 anyClass 这个接口或类。无论 anyClass 是 接口还是类,都使用 extends 关键字。

2.使用类型通配符

在泛型机制中,提供了类型通配符,其主要作用是在创建一个泛型类对象时,限制这个泛型类的类型实现或继承某个接口或类的子类。要声明这样一个对象可以使用“?”通配符来表示,同时使用extends关键字来对泛型加以限制。
使用泛型类型通配符的语法如下:

泛型类名称<? extends List> a = null;

其中,<? extends List> 表示类型未知,当需要使用该泛型对象时,可以单独实例化(List 就是要实现的接口)。

还可以将该实例放置在方法的参数中。

如果使用 A<?> 这种形式实例化泛型类对象,则默认表示可以将A指定为实例化Object及以下的子类类型。
在泛型中使用通配符形式:

	List<String> l1 = new ArrayList<String>();//实例化一个 ArrayList对象
	l1.add("Member");									 // 在集合中添加内容
	List<?> l2 = l1;										//使用通配符
	List<?> l3 = new LinkedList<Integer>();
	System.out.println(l2.get(0));				   //获取集合中的第一个值

List<?>类型的对象可以接受String类型的ArrayList集合,也可以接受Integer类型的LinkedList集合。
那么
List<?> l2 = l1 语句

List l2 = l1 语句 存在何种区别呢?

使用通配符声明的名称实例化的对象不能对其加入新的信息,只能获取或者删除。
如:

		l1.set(0,"member change");//没使用通配符的对象可以调用set()方法
		//l2.set(0,"member change");使用通配符的对象不可以调用
		//l3.set(0,1);
		l2.get(0);    //可以使用l2的实例获取集合中的值
		l2.remove(0);//根据键名删除集合中的值

泛型类型限制出了可以向下限制之外,还可以进行向上限制,只要在定义的时候使用super关键字即可。
如。“A<? super List> a = null;” 这样定义后,对象a只接受List接口或上层父类类型,如“a = new A< Object >();”

3.继承泛型类与实现泛型接口

public class ExtendsClass<T1>{
}
class SubClass<T1,T2,T3>extends ExtendsClass<T1>{
}

如果在SubClass类继承ExtendsClass类时保留父类的泛型类型,需要在继承时指明,若不指明,则SubClass类中的T1、T2、T3都会自动变为Object,所以一般情况下保留父类的泛型类型。

实现泛型接口:

public interface MyList<T> 
{ 
int size(); 
boolean isEmpty(); 
boolean contains(T o); 
boolean add(T o); 
}

总结:
1.泛型的类型参数只能是类类型,不可以是简单类型,如 A < int > 这种泛型定义就是错误的。
2.泛型的类型个数可以是多个。
3.可以使用extends关键字限制泛型类型。
4.可以使用通配符限制泛型类型。

附上使用接口和泛型自己重新定义的MyLinkedList类:

-----MyList.java-----
package homework5;

public interface MyList<T> 
{ 
int size(); 
boolean isEmpty(); 
boolean contains(T o); 
boolean add(T o); 
}


-----MyLinkedList.java-----
package homework5;
import java.util.Random;



class Node<T> 
{ 
T value; 
Node<T> next; 

public Node(T i) 
{ 
value = i; 
next = null; 
} 
} 

public class MyLinkedList<T> implements MyList<T> {
	Node<T> head; 

	public MyLinkedList() 
	{ 
	} 

	public MyLinkedList(T... values) 
	{ 
	if(values.length == 0) 
	return; 
	head = new Node<T>(values[0]); 
	Node<T> pre = head; 
	for(int i=1; i<values.length; i++) 
	{ 
	Node<T> node = new Node<T>(values[i]); 
	pre.next = node; 
	pre = node; 
	} 
	} 

	public void addToHead(T i) 
	{ 
	Node<T> node = new Node<T>(i); 
	node.next = head; 
	head = node; 
	} 

	public void addToTail(T i) 
	{ 
	if (head == null) 
	{ 
	head = new Node<T>(i); 
	return; 
	} 

	Node<T> tail = head; 
	while(tail.next != null) 
	{ 
	tail = tail.next; 
	} 

	Node<T> node = new Node<T>(i); 
	tail.next = node; 
	} 

	public String toString() 
	{ 
	String str = ""; 
	Node<T> node = head; 
	while(node != null) 
	{ 
	str += String.format("%d--> ", node.value); 
	node = node.next; 
	} 
	return str; 
	} 
	//
	@Override
	public int size()
	{
		int count = 0;
		Node<T> temp = head;
		while(temp!= null)
		{
			count++;
			temp = temp.next;
		}
		
		return count;
		
	}
	//
	@Override
	public boolean isEmpty()
	{
		return head == null;
	}
	//
	@Override
	public boolean contains(T o) { 
		
		boolean find = false;
		Node<T> temp = head;
		if(o == null)
		{
			return find;
		}
		while(temp!= null)
		{
			if(temp.value.equals(o))
			{
				find = true;
			}
			temp = temp.next;
		}
		
		return find;
		
	}
	//
	@Override
	public boolean add(T o) {
		boolean judge = false;
		if(o == null)
			return judge;
		addToHead(o);
judge = true;
		return judge;		
		
	}

	
	
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		MyLinkedList<Integer> l = new MyLinkedList<Integer>(); 
		Random rd = new Random(); 
		for(int i=1; i<10; i++) 
		{ 
		l.addToTail(rd.nextInt(100)); 
		} 
		l.addToTail(200); 
		l.addToHead(200); 
		System.out.println(l); 
		System.out.println(l.size()); 
		System.out.println(l.isEmpty()); 
		System.out.println(l.contains(200)); 
		System.out.println(l.contains(null)); 
		System.out.println(l.add(222)); 
		System.out.println(l); 


		l = new MyLinkedList(1, 2, 3, 4); 
		System.out.println(l); 
		System.out.println(l.size()); 
		System.out.println(l.size()); 
		System.out.println(l.isEmpty()); 
		System.out.println(l.contains(200)); 
		System.out.println(l.contains(null)); 
		System.out.println(l.add(null)); 
		System.out.println(l);
	}

}

以及输出:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值