Java面向对象编程_抽象类&接口&包装类&泛型

总览:

在这里插入图片描述


抽象类与接口

在这里插入图片描述

1,抽象类

在这里插入图片描述

demo_抽象类
//抽象类:1.不能和final关键字一起定义,因为抽象类必须有子类,但final不允许继承
//2.抽象类是普通类的升级版,可以有构造方法,static。。。
abstract class 抽象父类//利用abstract来定义抽象类
{
	private String say;
	abstract public void print();//利用abstract来定义抽象方法,抽象方法是没有具体操作的因此没有{};
	public void setSay(String say){//抽象类中的普通方法
		this.say=say;
	}
	public String getSay(){
		return this.say;
	}
}
class 子类 extends 抽象父类//抽象类不能直接使用需要被子类继承,并且子类必须覆写抽象类中的抽象方法
{
	public void print(){//覆写抽象类中的抽象方法
		System.out.println("子类覆写抽象类方法");
	}
}
public class 抽象类
{
	public static void main(String agrs[]){
		抽象父类 a=new 子类();//抽象类由于不能直接实例化所以要借助继承子类向上转型来间接实例化
		a.setSay("利用子类设置抽象类属性");
		System.out.println(a.getSay());
		a.print();
	}
}
//抽象类使用的很大程度上有一个核心的问题:抽象类自己无法直接实例化
//抽象类之中主要的目的是进行过渡操作使用,属于党内要使用抽象类进行开发的时候,往往都是在你设计中需要解决继承问题时所带来的代码重复处理
demo_模板设计模式
//抽象类的应用:模板设计模式
//通过抽象类提供的抽象方法将其作为子类方法的模板完成统一方法的管理,抽象类自身通过一些普通方法来统一对抽象方法进行调用
abstract class Action
{
	public static final int EAT=1;
	public final static int REST=5;
	public final static int WORK=10;

	public void actionSwitch(int code){
		switch(code){
			case EAT:{
				 this.eat();
				 break;
			}
			case REST:{
				this.rest();
				break;
			}
			case WORK:{
				this.work();
				break;
			}
		}
	}

	abstract public void eat();//模板
	abstract public void rest();
	abstract public void work();

}
class Robot extends Action
{
	public void eat(){}
	public void rest(){}
	public void work(){
		System.out.println("机器人重复性的工作");
	}
	
}
class Person extends Action
{
	public void eat(){
		System.out.println("人优雅的吃饭");
	}
	public void rest(){
		System.out.println("人在床上睡觉");
	}
	public void work(){
		System.out.println("人勤奋的工作");
	}
}
class Pig extends Action
{
	public void eat(){
		System.out.println("猪狼吞虎咽的吃饭");
	}
	public void rest(){
		System.out.println("猪席地而睡");
	}
	public void work(){}
}
public class 抽象类_模板设计模式
{
	public static void main(String agrs[]){
		Action per=new Person();
		Action rob=new Robot();
		Action pig=new Pig();
		System.out.println("--------------------人-----------------");
		per.actionSwitch(1);
		per.actionSwitch(5);
		per.actionSwitch(10);
		System.out.println("------------------机器人-----------------");
		rob.actionSwitch(1);
		rob.actionSwitch(5);
		rob.actionSwitch(10);
		System.out.println("--------------------猪-----------------");
		pig.actionSwitch(1);
		pig.actionSwitch(5);
		pig.actionSwitch(10);

	}
}

2,包装类

在这里插入图片描述

demo_包装类
//java是以类对象为主的,但基本数据类型并不是标准类,无法与类对象操作,为了解决这个问题,诞生了包装类对基本数据类型进行转换
//包装类将基本数据类型转换为类的原理:
class Int//包装类原理
{
	private int data;
	public Int(int data){
		this.data=data;
	}
	public int intValue(){
		return this.data;
	}
}
public class 包装类{
	public static void main(String agrs[]){

		//利用原理实现:
		Object obj=new Int(10);//将基本数据类型int(10)装箱至Int包类,在向上转型为Object
		System.out.println(((Int)obj).intValue());//将Int包向下转型至Int,利用普通方法intValue拆箱
		
		//为了方便开发者,系统也提供了系统的包装类:【数值型包装类 Number类】(Byte,Short,Integer,Long,Float,Double为Number的子类)【对象型包装类】(Boolean类,Character类)
		//装箱:包装类名(基本数据类型值);如Byte(10); 拆箱:基本数据类型Value();如intValue();
		Integer data=new Integer(10);//装箱
		int num=data.intValue();//拆箱
		System.out.println(num);

		//在JDK1.5后开始了自动装箱拆箱;
		Integer a=10;
		int x= ++a;//现在自动装箱的a可以直接用于基本数据类型参与赋值,数学运算
		a--;
		System.out.println(x);

		//和String类一样:String类存在在直接赋值和构造方法赋值的两种情况下数据比较的问题
		//包装类由于有手动装箱和自动装箱两种方式也存在数据比较的问题
		//自动装箱好比String类的直接赋值,相同数据入同一池。手动装箱好比String类的构造方法赋值,在“==”使用时要注意
		//在数据比较时保险一点的方法是利于包装类提供的equals方法来比较同种包类数据,(此equals方法是包装类覆写的Object类equals方法)
		System.out.println(a.equals(data));
	}
}

3,接口

在这里插入图片描述

demo_接口
//接口:接口是一种特殊的类,用interface定义不用class,接口的成员属性一般为全局常量,方法为抽象方法
//使用接口的目的:接口的成员属性与方法可以将属性和方法名称暴露给接口使用者,而内部的接口方法具体实现是靠子类实现,对外部人隐藏。
//由于接口使用抽象方法所以接口无法实例化,如同抽象类,需要子类向上转型实例化,需要子类实现接口并覆写接口方法,才可使用。
//接口存在子类实现操作 实现由implements定义,接口间也存在继承,当子类既要实现又要继承时按照先继承再实现的规矩
//子类可继承多个接口,但只能继承一个普通类。子类可以实现多个接口。
//子类在实现接口时要把接口的抽象方法全部覆写。
//JDK1.8后接口得到强化接口中可以加入static方法与default方法用于纠正接口初期设计不足
abstract class Welcome
{
	public abstract void welcome();
}
interface IMessage
{
	public static final String INFO="接口";
	public abstract void getInfo();
}
interface IChannel
{
	public abstract boolean channelConnect();
}
interface IDatabase
{
	public abstract boolean databaseConnect();
}
interface IService extends IChannel,IDatabase//接口间的继承:一个接口可继承多个接口,且不用覆写继承的接口方法
{
	public abstract String service(); 
}
class MessageService extends Welcome implements IMessage,IService
{
	public void welcome(){
		System.out.println("欢迎使用信息服务");
	}
	public boolean channelConnect(){
		return true;
	}
	public boolean databaseConnect(){
		return true;
	}
	public String service(){
		return "服务连接成功";
	}
	public void getInfo(){
		this.welcome();
		if(this.channelConnect()){
			if(this.databaseConnect()){
				System.out.println(this.service());
			}else{
				System.out.println("数据库连接错误");
			}
		}else{
			System.out.println("频道连接错误");
		}
	}

}
public class 接口
{
	public static void main(String agrs[]){
		IMessage mess=new MessageService();//子类向上转型实例化接口
		mess.getInfo();
	}
}
demo_工厂设计模式
//工厂设计模式:通过定义子类调度类(Factory)来分配实现客户端(主类)的自定义接口实现
interface IEat
{
	public void eat();
}
class Bread implements IEat
{
	public void eat(){
		System.out.println("吃面包");
	}
}
class Milk implements IEat
{
	public void eat(){
		System.out.println("喝牛奶");
	}
}
class Factory//根据客户端需求的不同调度不同的接口实现
{
	public static IEat factoryGet(String food){
		if(food.equals("bread")){
			return new Bread();
		}else if(food.equals("milk")){
			return new Milk();
		}
		return null;
	}
}
public class 工厂设计模式
{
	public static void main(String agrs[]){
		IEat food=Factory.factoryGet(agrs[0]);
		food.eat();
	}
}
demo_代理设计模式
//代理设计模式:定义一个接口标准,接口的实现分别由两个子类实现,一个用于核心功能的实现(如EatReal),一个用于辅助功能的实现(如EatProxy)
//核心实现主要实现接口标准所定义的核心功能,代理功能实现主要实现对辅助功能的实现与核心功能,辅助功能的总和
interface IEat
{
	public void get();
}
class EatReal implements IEat
{
	public void get(){
		System.out.println("[核心主题]:吃到了饭");
	}
} 
class EatProxy implements IEat
{
	private IEat eat;
	public EatProxy(IEat eat){
		this.eat=eat;
	}
	public void get(){
		this.prepare();
		this.eat.get();
		this.clean();
	}
	public void prepare(){
		System.out.println("[代理主题]:准备食物");
	}
	public void clean(){
		System.out.println("[代理主题]:清理食物");
	}
}


public class 代理设计模式
{
	public static void main(String agrs[]){
		IEat eat=new EatProxy(new EatReal());
		eat.get();
	}
}
demo_工厂设计模式与代理设计模式结合
interface IEat{
    void eat();
}
class Milk implements IEat{
    @Override
    public void eat() {
        System.out.println("喝牛奶");
    }
}
class Bread implements IEat{
    @Override
    public void eat() {
        System.out.println("吃面包");
    }
}
class EatProxy implements IEat{
    IEat eat;
    public EatProxy(IEat eat) {
        this.eat = eat;
    }
    @Override
    public void eat() {
        this.prepare();
        eat.eat();
        this.end();
    }
    public void prepare(){
        System.out.println("开始进食");
    }
    public void end(){
        System.out.println("结束进食");
    }
}
class Factory{
    private Factory(){}
    public static IEat factory(String food){
        switch (food){
            case "milk":
                return new EatProxy(new Milk());
            case "bread":
                return  new EatProxy(new Bread());
            default:return null;
        }
    }
}
public class Demo {
    public static void main(String[] args) {
        IEat eat=Factory.factory("milk");
        eat.eat();
    }
}

4,泛型

在这里插入图片描述

demo_泛型问题的引出
//泛型:JDK1.5后为了解决向下转型的安全问题
class Point
{
	private Object x;
	private Object y;
	public void setX(Object x){
		this.x=x;
	}
	public void setY(Object y){
		this.y=y;
	}
	public Object getX(){
		return this.x;
	}
	public Object getY(){
		return this.y;
	}

}
public class 泛型_问题引出
{
	public static void main(String agrs[]){
		Point point= new Point();
		point.setX(20);
		point.setY("东经120度");
		int x=(Integer)point.getX();
		int y=(Integer)point.getY();
		System.out.println("X="+x+",Y="+y);
		//编译通过,但运行提示“ClassCastException”。这是由于设计Point类时由于数据是以Object类接收的(任何数据自动向上转型为Object类)
		//在客户端(主类)定义实例化对象(point)的时候由于使用者按照统一的数据类型(Integer)进行向下转型来获取数据(为Object类)时如果用户输入的值与预期不符(如应为int类结果输入了“东经120度”的String)此时由于是用Object类进行数据接收所以编译时不提示错误,但运行时会出现错误
		//这是因为误将String类保存为Object类又在客户端统一操作时向下转型为Integer类所出现的问题
		//实际上错误的本质在于 Object类可接收数据范围过大 且 客户端统一操作的向下强制转型存在安全隐患
		//使用泛型可以规避大部分这种问题 起码编译时会提错。
	}
}
demo_泛型使用
//泛型设计思想:类中的属性和方法的参数与返回值的类型,采用动态标记,在对象实例化的时候,动态配置要使用的数据类型
//泛型的默认数据类型为Object类【与旧版程序兼容】
class Point <T>//对类使用泛型
{
	private T saidOne;
	public void setOne(T saidOne){
		this.saidOne=saidOne;
	}
	public void said(){
		System.out.println("One="+this.saidOne);
	}

}

public class 泛型_使用
{
	public static void main(String agrs[]){
		Point<Integer> point=new Point<Integer>();//客户端明确类泛型为包装类Integer
		//在JDK5-7时要求定义泛型在声明对象和实例化对象时需要明确泛型的类型【包装类(数值型Number类的子类与引用型Boolean类与Character类)】,
		//在JDK7后允许实例化对象时不明确:Point<Integer> point=new Point();
		point.setOne(1);//自动装箱,若采集错误类型数据如String类【会在编译时提错】
		fun(point);
		funA(point);


		Point<String> pointB=new Point();
		pointB.setOne("Hello");
		funB(pointB);

		
	}
	public static void fun(Point<?> temp){//泛型通配符<?>:<?>由于声明接收任意类型的实例化对象,但只允许获取数据,不允许修改数据
		//该方法也可用不设置泛型的形式(Point temp)来接收实例化对象,按与泛型的差别是可以获取数据也允许修改数据
		//此处用temp.setOne(3);修改数据,编译时会提示“不兼容的类型: int无法转换为CAP#1”
		temp.said();
	}
	
	public static void funA(Point<? extends Number> temp){//泛型上限<?extends 类>:只能使用当前类或该类的子类【该接口或其实现】
		//此方法可用类型:Number类及其子类Integer Short Byet Long Double Float
		temp.said();
	}
	public static void funB(Point<? super String> temp){//泛型下限<?super 类>:只能使用该类或该类的父类【该接口或其父接口】
		//此方法可用类型:String类及其父类Object类
		temp.said();
	}
}
demo_泛型接口与方法
//泛型不仅仅定义在类上,还可定义在方法和接口上
//泛型接口的子类实现有两种:1.子类继续声明泛型。2.子类为接口实现设置泛型类型
interface IMessage <T>//泛型接口
{
	public abstract String echo(T mess);
}
class MessageA<S> implements IMessage<S>//子类继续声明泛型。
{

	public String echo(S mess){
		return "消息:"+mess;
	}
}
class MessageB implements IMessage<String>//子类为接口实现设置泛型类型。
{

	public String echo(String mess){
		return "消息:"+mess;
	}
}
public class 泛型_接口和方法
{
	public static void main(String agrs[]){
		IMessage<String> mess=new MessageA<String>();
		System.out.println(mess.echo("Hello"));
		IMessage<String> mes=new MessageB();//不能改为:IMessage<String> mes=new MessageB<String>();因为MessageB是没有泛型的
		System.out.println(mes.echo("Hello"));

		fun(3.14);
	}
	public static<T> void fun(T temp){//泛型方法
		System.out.println(temp);
	}
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值