黑马程序员_面向对象(2) 接口&抽象类&内部类

本文详细介绍了抽象类、接口和内部类在Java编程中的核心概念与实际应用,包括它们的区别、特点及如何在程序设计中有效利用。通过实例解析,帮助开发者更好地理解和掌握这些高级特性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

------- android培训 java培训 、期待与您交流! ----------

一.抽象类

特点:

1.方法只有声明没有实现时,该方法就是抽象方法,需要被abstract修饰。抽象方法必须定义在抽象类中。该类必须也被abstract修饰。

2.抽象类不可以被实例化。为什么?因为调用抽象方法没有意义。

3.抽象类必须由其子类覆盖所有的抽象方法后,该子类才可以实例化。否则,这个子类还是抽象类

抽象类和一般类区别。

相同点:抽象类和一般类都是用来描述事物的,都在内部定义了成员。

不同:

1.一般类有足够的信息描述事物,抽象类描述事物的信息有可能不足。

2.一般类中不能定义抽象方法,只能定义非抽象方法。抽象类中既可以定义抽象方法也可以定义非抽象方法。

3.一般类可以被实例化,抽象类不可以被实例化。

5.抽象类一定是个父类吗?

是的。因为需要子类覆盖其方法后才可以对子类实力话


抽象类中是否有构造函数?
有,抽象类是一个父类,要给子类提供实例的初始化

abstract 关键字,和哪些关键字不能共存。
final:不行,被final修饰的类不能有子类。而被abstract修饰的类一定是一个父类。
private: 不行,抽象类中的私有的抽象方法,不被子类所知,就无法被复写。而抽象方法出现的就是需要被复写。
static:不行,如果static可以修饰抽象方法,那么连对象都省了,直接类名调用就可以了。可是抽象方法运行没意义。
 
抽象类代码eg:
// 描述员工

class Employee
{
	private String name;
	private String id;
	private double pay;

	Employee(String name,String id,double pay)
	{
		this.name = name;
		this.id = id;
		this.pay = pay;
	}
	
	// 抽象方法
	public abstract void work();

}


// 描述经理

class Manager extends Employee
{
	private int bonus;
	Manager(String name,String id,double pay,int bonus)
	{
		super(name,id,pay);
		this.bonus = bonus;
	}
	// 覆写
	public void work()
	{
		System.out.println("manager work");
	}
}
// 描述工人
class Pro extends Employee
{
	Pro(String name,String id,double pay)
	{
		super(name,id,pay);
	}
	//覆写
	public void work()
	{
		System.out.println("pro work");
	}
}

面试题: 抽象类与接口区别:
   声明方法的存在而不去实现它的类被叫做抽象类(abstract class),它用于要创建一个体现某些基本行为的类,并为该类声明方法,但不能在该类中实现该类的情况。不能创建abstract 类的实例。然而可以创建一个变量,其类型是一个抽象类,并让它指向具体子类的一个实例。不能有抽象构造函数或抽象静态方法。Abstract 类的子类为它们父类中的所有抽象方法提供实现,否则它们也是抽象类为。取而代之,在子类中实现该方法。知道其行为的其它类可以在类中实现这些方法。  
   接口(interface)是抽象类的变体。在接口中,所有方法都是抽象的。多继承性可通过实现这样的接口而获得。接口中的所有方法都是抽象的,没有一个有程序体。接口只可以定义static final成员变量。接口的实现与子类相似,除了该实现类不能从接口定义中继承行为。当类实现特殊接口时,它定义(即将程序体给予)所有这种接口的方法。然后,它可以在实现了该接口的类的任何对象上调用接口的方法。由于有抽象类,它允许使用接口名作为引用变量的类型。通常的动态联编将生效。引用可以转换到接口类型或从接口类型转换,instanceof 运算符可以用来决定某对象的类是否实现了接口
-------------------------------------------------------------------------------------------------------------------------

二.接口

接口:是不可以创建对象的,因为有抽象方法。

需要被子类实现,子类对接口中的抽象方法全都覆盖后,子类才可以实例化。

否则子类是一个抽象类。

 

接口可以被类多实现,也是对多继承不支持的转换形式。java支持多实现,中间用逗号分割。也可以在继承一个类的同时实现多个接口。

 

接口中的常量都是静态的,可以静态调用,也可以通过接口名调用。

 

接口的特点:

1.接口是对外暴漏的规则

2.接口是程序的扩展

3.接口可以多实现

4.类与接口之间是实现关系,而且类可以继承一个类的同时实现多个接口。

5.接口与接口之间可以有继承关系。都没有方法体甚至可以多继承。

 eg: 

interface Inter
{
	public static final int NUM = 3;
	public abstract void show();
}

interface InterA
{
	public abstract void show();
}

class Demo
{
	public void function(){}
}

class Test extends Demo implements Inter,InterA
{
	public void show(){}
}

接口与抽象类 共 性:都是不断抽取出来的抽象的概念

接口与抽象类区别:

区别 1:抽象类体现继承关系,一个类只能单继承,接口体现实现关系,一个类可以多实现

区别 2:抽象类是继承,是 "is a "关系,接口是实现,是 "like a"关系

区别 3:抽象类中可以定义非抽象方法,供子类直接使用,接口的方法都是抽象,接口中的成员都有固定修饰符

 

eg:
 
interface A
{
	void methodA();
}
interface B //extends A
{
	void methodB();
}

interface C extends B,A//接口之间可以多继承
{
	void methodC();
}

class D implements C
{
	public void methodA(){}
	public void methodC(){}
	public void methodB(){}
}


class InterfaceDemo 
{
	public static void main(String[] args) 
	{
		Test t = new Test();
		System.out.println(t.NUM);//接口中的常量都是静态的,可以静态调用,也可以通过接口名调用。
		System.out.println(Test.NUM);
		System.out.println(Inter.NUM);

	}
}

接口多态应用:
eg:
 
/*
需求:数据库的操作。
数据是:用户信息。
1,连接数据库。JDBC  Hibernate
2,操作数据库。
	c create r read  u update  d delete
3,关闭数据库连接。
*/

interface UserInfoDao
{
	public void add(User user);

	public void delete(User user);
}

class UserInfoByJDBC implements UserInofDao
{

	public void add(User user)
	{
		1,JDBC连接数据库。;
		2,使用sql添加语句添加数据。;
		3,关闭连接。
	}
	public void delete(User user)
	{
		1,JDBC连接数据库。;
		2,使用sql添加语句删除数据。;
		3,关闭连接。
	}
}

class UserInfoByHibernate implements UserInfoDao
{
	public void add(User user)
	{
		1,Hibernate连接数据库。;
		2,使用sql添加语句添加数据。;
		3,关闭连接。
	}
	public void delete(User user)
	{
		1,Hibernate连接数据库。;
		2,使用sql添加语句删除数据。;
		3,关闭连接。
	}
}

class  DBOperate
{
	public static void main(String[] args) 
	{
		//UserInfoByJDBC ui = new UserInfoByJDBC();
//		UserInfoByHibernate ui = new UserInfoByHibernate();
		UserInfoDao ui = new UserInfoByHibernate();
		ui.add(user);
		ui.delete(user);
	}
}

接口应用:
/*
需求:
电脑运行实例,
电脑运行基于主板。
*/


interface PCI
{
	public void open();
	public void close();
}

class MainBoard
{
	public void run()
	{
		System.out.println("mainboard run ");
	}
	public void usePCI(PCI p)//PCI p = new NetCard()//接口型引用指向自己的子类对象。
	{
		if(p!=null)
		{
			p.open();
			p.close();
			
		}
	}
}


class NetCard implements PCI
{
	public void open()
	{
		System.out.println("netcard open");
	}
	public void close()
	{
		System.out.println("netcard close");
		method();
	}
	
}
class SoundCard implements PCI
{
	public void open()
	{
		System.out.println("SoundCard open");
	}
	public void close()
	{
		System.out.println("SoundCard close");
	}
}

class DuoTaiDemo5 
{
	public static void main(String[] args) 
	{
		MainBoard mb = new MainBoard();
		mb.run();
		mb.usePCI(null);
		mb.usePCI(new NetCard());
		mb.usePCI(new SoundCard());
		
	}
}

-------------------------------------------------------------------------------------------------------------------------

三.内部类

1,内部类可以直接访问外部类中的成员,包括私有。

之所以可以直接访问外部类中的成员,是因为内部类中持有了一个外部类的引用,格式 外部类名.this

2,外部类要访问内部类,必须建立内部类对象

eg:

class Outer
{
	private int x = 3;

	
	class Inner//内部类
	{
		//int x = 4;
		void function()
		{
			//int x = 6;
			System.out.println("innner :"+Outer.this.x);
		}
	}

	/**/
	void method()
	{
		Inner in = new Inner();
		in.function();
	}
}


class  InnerClassDemo
{
	public static void main(String[] args) 
	{
		Outer out = new Outer();
		out.method();

		//直接访问内部类中的成员。
//		Outer.Inner in = new Outer().new Inner();
//		in.function();
	}
}

访问格式:
1,当内部类定义在外部类的成员位置上,而且非私有,可以在外部其他类中。
可以直接建立内部类对象。
格式
外部类名.内部类名  变量名 = 外部类对象.内部类对象;
Outer.Inner in = new Outer().new Inner();


2,当内部类在成员位置上,就可以被成员修饰符所修饰。
比如,private:将内部类在外部类中进行封装。
static:内部类就具备static的特性。
当内部类被static修饰后,只能直接访问外部类中的static成员。出现了访问局限。
在外部其他类中,如何直接访问static内部类的非静态成员呢?
new Outer.Inner().function();
在外部其他类中,如何直接访问static内部类的静态成员呢?
uter.Inner.function();
注意:当内部类中定义了静态成员,该内部类必须是static的。
 当外部类中的静态方法访问内部类时,内部类也必须是static的。


内部类定义在局部时,
1,不可以被成员修饰符修饰
2,可以直接访问外部类中的成员,因为还持有外部类中的引用。
     但是不可以访问它所在的局部中的变量。只能访问被final修饰的局部变量

eg:

class Outer
{
	int x = 3;

	void method(final int a)
	{
               // 访问finall 修饰的局部变量
		final int y = 4;

            // 不可以有成员修饰符修饰
		class Inner
		{
			void function()
			{
				System.out.println(y);
			}
		}
	   
		new Inner().function();
		
	}
}


class  InnerClassDemo3
{
	public static void main(String[] args) 
	{
		Outer out = new Outer();
		out.method(7);
		out.method(8);
	}

}

匿名内部类:
1,匿名内部类其实就是内部类的简写格式。
2,定义匿名内部类的前提:
     内部类必须是继承一个类或者实现接口。
3,匿名内部类的格式:  new 父类或者接口(){定义子类的内容}
4,其实匿名内部类就是一个匿名子类对象。而且这个对象有点胖。可以理解为带内容的对象。
5,匿名内部类中定义的方法最好不要超过3个
    eg:
abstract class AbsDemo
{
	abstract void show();
	
}
class Outer
{
	int x = 3;

	/*
	class Inner extends AbsDemo
	{
		int num = 90;
		void show()
		{
			System.out.println("show :"+num);
		}
		void abc()
		{
			System.out.println("hehe");
		}
	}
	*/

	public void function()
	{
		//AbsDemo a = new Inner();
//		Inner in = new Inner();
//		in.show();
//		in.abc();
	
                 //内部类
		AbsDemo d = new AbsDemo()
		{
			int num = 9;
			void show()
			{
				System.out.println("num==="+num);
			}
			void abc()
			{
				System.out.println("haha");
			}
		};
		d.show();
		//d.abc();//编译失败;
	}



-------android培训java培训、期待与您交流! ----------
资源下载链接为: https://pan.quark.cn/s/f989b9092fc5 今天给大家分享一个关于C#自定义字符串替换方法的实例,希望能对大家有所帮助。具体介绍如下: 之前我遇到了一个算法题,题目要求将一个字符串中的某些片段替换为指定的新字符串片段。例如,对于源字符串“abcdeabcdfbcdefg”,需要将其中的“cde”替换为“12345”,最终得到的结果字符串是“ab12345abcdfb12345fg”,即从“abcdeabcdfbcdefg”变为“ab12345abcdfb12345fg”。 经过分析,我发现不能直接使用C#自带的string.Replace方法来实现这个功能。于是,我决定自定义一个方法来完成这个任务。这个方法的参数包括:原始字符串originalString、需要被替换的字符串片段strToBeReplaced以及用于替换的新字符串片段newString。 在实现过程中,我首先遍历原始字符串,查找需要被替换的字符串片段strToBeReplaced出现的位置。找到后,就将其替换为新字符串片段newString。需要注意的是,在替换过程中,要确保替换操作不会影响后续的查找和替换,避免遗漏或重复替换的情况发生。 以下是实现代码的大概逻辑: 初始化一个空的字符串result,用于存储最终替换后的结果。 使用IndexOf方法在原始字符串中查找strToBeReplaced的位置。 如果找到了,就将originalString中从开头到strToBeReplaced出现位置之前的部分,以及newString拼接到result中,然后将originalString的查找范围更新为strToBeReplaced之后的部分。 如果没有找到,就直接将剩余的originalString拼接到result中。 重复上述步骤,直到originalStr
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值