黑马程序员__JAVA基础__面向对象(三)

 -------android培训java培训、java学习型技术博客、期待与您交流! ------------

 

1.抽象类

抽象定义:

    抽象就是从多个事物中将共性的,本质的内容抽取出来。例如:狼和狗的共性都是犬科,犬科就是抽象出来的概念。

抽象类:

    java中可以定义没有方法体的方法,该方法的具体实现由子类完成,该方法称为抽象方法,包含抽象方法的类就是抽象类。

抽象方法的由来:

    多个对象都具备相同的功能,但是功能具体内容有所不同,那么在抽取过程中,只抽取了功能定义,并未抽取功能主体,那么只有功能声明,没有功能主体的方法称为抽象方法。

    例如:狼和狗都有吼叫的方法,可以吼叫的内容是不一样的,所以抽取出来的犬科虽然有吼叫功能,但是并不明确吼叫的细节。

抽象类的特点:

    1.抽象类和抽象方法必须用abstract关键字来修饰。

    2.抽象方法只有方法声明,没有方法体,定义在抽象类中。

        格式:修饰符 abstract 返回值类型 函数名(参数列表);

    3.抽象类不可以被实例化,也就是不可以用new创建对象。原因如下:

        抽象类是具体事物抽取出来的,本身是不具体的,没有对应的实例,例如:犬科是一个抽象的概念,真正存在的是儿狼和狗。而且抽象类即使创建了对象,调用抽象方法也没有意义。

    4.抽象类通过其子类实例化,而子类需要覆盖掉抽象类中所有的抽象方法后才可以创建对象,否则子类也是抽象类。

基本抽象类代码:

abstrack class Student//抽象类
{
  abstrack void study();//抽象方法
}

class BaseStudent extends Student//继承抽象类
{
  void study()//覆盖父类方法
  {
  	System.out.prinln("base study");
  }
}

class AdvStudent extends Student//继承抽象类
{
  void study()//覆盖父类方法
    {
  	System.out.println("Adv study");
  }
}

class AbstrackDemo
{
  public static void main(String[] args)
  {
  	System.out.println("抽象类示例");
  }
}


继承与抽象练习:

/*
对员工建模,员工包含3个属性:姓名,工号,工资。经理除了包含员工的属性之外,还有一个奖金属性。
*/
abstrack class Employee//员工类,父类
{
  //员工的3个属性
  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);//利用super调用父类构造函数
  	this.bonus = bonus;
  }
  
  public void work()//经理工作方法
  {
  	System.out.println("manager work");
  }
}
  
class Pro extends Employee//普通员工继承员工类
{
  Pro(String name,String id,String pay)//员工类自定义构造函数
  {
  	super(name,id,pay);
  }
  public void work()//普通员工工作方法	
  {
  	System.out.println("pro work");
  }
}
  
class Demo
{
  public static void main(String[] args)
  {
  	System.out.println("Demo");
  }
}
  
//注:构造函数:给对应对象进行初始化。

 

抽象类相关问题:

1.抽象类中是否有构造函数?

    答:有,抽象类是一个父类,要给子类提供一个实例的初始化。

2.抽象关键字abstrack不可以和哪些关键字共存?

    答:fianl,被final修饰的类是不能有子类的,而被abstrack修饰的类一定是一个父类

        private,抽象类中的私有的抽象方法是不能被子类所复写的。而抽象方法是子类必须复写的。

        static,static修饰抽象方法,通过类名调用抽象方法是没有意义的。

3.抽象类中可不可以没有抽象方法?

    答:抽象类中可以不定义抽象方法,这样做仅仅是不让该类建立对象。


 

2.接口

格式:interface {}

接口中的成员修饰符是固定的:

    成员常量:public static final

    成员函数:public abstrack(接口中的成员都是public修饰的)

接口的出现将“多继承”通另一种形式体现出来,即“多实现”。

接口的特点:

    1.接口是对外暴露的规则。

    2.接口是程序的功能扩展。

    3.接口可以用来多实现。

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

    5.接口与接口之间可以有继承关系。

接口示例:

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//继承Demo,实现两个接口
{
	public void show(){}
}

class InterfaceDemo 
{
	public static void main(String[] args) 
	{
		Test t = new Test();
		System.out.println(t.NUM);//Test实现了Inter接口
		//Test实现了Inter接口,通过类名调用被static修饰的成员
		System.out.println(Test.NUM);
		//类名直接调用被static修饰的成员
		System.out.println(Inter.NUM);
	}
}
//输出结果:
3
3
3


3.多态

定义:某一类事物的多种存在形态。

    例如:动物中猫,狗

猫这个对象对应的类型是猫类型:猫 x = new 猫();

同时猫也是动物中的一种,也可以把猫称为动物:动物 y = new 猫();

动物是猫和狗具体事物中抽取出来的父类型。

父类型引用指向子类对象。

体现:父类或者接口的引用指向或者接收自己的子类对象

作用:多态的存在提高了程序的扩展性和后期可维护性

前提:1.需要存在继承或者实现关系。2.要有覆盖操作。

多态的特点

    成员函数:

        在编译时:要查看引用变量所属的类中是否有所调用的成员。

        在运行时:要查看对象所属的类中是否有所调用的成员。

    成员变量:只看引用变量所属的类。

多态示例代码:

abstract class Animal//抽象类
{
	abstract void eat();//动物都有吃的属性
}

class Cat extends Animal//猫继承动物类
{
	//猫的特有方法
	public void eat()
	{
		System.out.println("吃鱼");
	}
	public void catchMouse()
	{
		System.out.println("抓老鼠");
	}
}


class Dog extends Animal//狗继承动物类
{
	//定义狗的特有方法
	public void eat()
	{
		System.out.println("吃骨头");
	}
	public void kanJia()
	{
		System.out.println("看家");
	}
}


class Pig extends Animal//猪继承动物类
{
	//定义猪的特有方法
	public void eat()
	{
		System.out.println("饲料");
	}
	public void gongDi()
	{
		System.out.println("拱地");
	}
}

class DuoTaiDemo 
{
	public static void main(String[] args) 
	{
		//多态的实现
		Animal a = new Cat();//类型提升。 向上转型。
		a.eat();
		

		Cat c = (Cat)a;//强制将父类的引用转成子类类型,向下转型。
		c.catchMouse();


		function(new Dog());

	}
	//定义一个方法,实现子类的特有功能
	public static void function(Animal a)//Animal a = new Cat();
	{
		a.eat();
		if(a instanceof Cat)
		{
			Cat c = (Cat)a;
			c.catchMouse();
		}
		else if(a instanceof Dog)
		{
			Dog c = (Dog)a;
			c.kanJia();
		}	
	}
}

上述代码知识点:

转型:

    Animal a = new Cat();//类型提升,向上转型。

    Cat c = (Cat)a;//强制将父类的引用转成子类类型,向下转型。

instanceof : 用于判断对象的类型。 对象 intanceof 类型(类类型 接口类型) 

 

多态中成员的特点分析:

class Fu//定义父类
{
	int num = 5;
	static int num2 = 4;
	void method1()
	{
		System.out.println("fu method_1");
	}
	void method2()
	{
		System.out.println("fu method_2");
	}
	static void method4()
	{
		System.out.println("fu method_4");
	}
}

class Zi extends Fu//定义子类并继承父类
{
	int num = 8;
	static int num2 = 9;
	void method1()//覆盖父类方法
	{
		System.out.println("zi method_1");
	}
	void method3()//子类特有方法
	{
		System.out.println("zi method_3");
	}

	static void method4()
	{
		System.out.println("zi method_4");
	}
}
class  DuoTaiDemo
{
	public static void main(String[] args) 
	{
		
		Fu f = new Zi();//编译的时候对象没有产生,直接看左边
		f.method1();//打印“zi method_1”,父类引用指向子类对象
		f.method2();//打印“fu method_2”,子类继承父类方法
		f.method3();//编译失败,因为父类中没有找到此方法
		//--------------------------------------------------------

		Fu f = new Zi();
		System.out.println(f.num);//输出结果:5
		//成员变量都参考引用型变量所属的类,这个地方是Fu类

		Zi z = new Zi();
		System.out.println(z.num);//输出结果:8
		//--------------------------------------------------------

		Fu f = new Zi();
		f.method4();//输出结果:“fu method_4”

		Zi z = new Zi();
		z.method4();//输出结果:“zi method_4”

		//静态方法在多态中直接参考左边,如上两类一进内存,静态直接就存在,这个时候是不用对象的

		//--------------------------------------------------------
		Fu f = new Zi();
		System.out.println(f.num2);//输出结果:4

		Zi z = new Zi();
		System.out.println(z.num2);//输出结果:9
		//静态的成员变量调用也是参考左边,静态其实参考的就是那个类
	}
}

结论:

    1.多态中成员函数的特点:

        在编译时期:参阅引用型变量所属的类中是否有调用的方法。如果有,编译通过,如果没有编译失败。

        在运行时期:参阅对象所属的类中是否有调用的方法。

        成员函数在多态调用时,编译看左边,运行看右边。

    2.多态中成员变量的特点:

        无论编译和运行,都参考左边(引用型变量所属的类)。

    3.在多态中,静态成员函数与静态变量的特点:

        无论编译和运行,都参考做左边。

 

4.内部类

当描述事物时,事物的内部还有事物,该事物用内部类来描述。因为内部事务在使用外部事物的内容。

将一个类定义在另一个类的里面,对里面那个类就称为内部类(内置类,嵌套类)。

访问特点:内部类可以直接访问外部类中的成员,包括私有成员。而外部类要访问内部类中的成员必须要建立内部类的对象

内部类定义在成员的位置上

    可以被private static成员修饰符修饰。被static修饰的内部类只能访问外部类中的静态成员

内部类定义在局部位置上:

    也可以直接访问外部类中的成员,同时可以访问所在局部中的局部变量,但必须是被final修饰的。

匿名内部类:就是内部类的简化写法。

    前提:内部类要继承或实现一个外部类或者接口。

    格式为:new 外部类名或者接口名(){覆盖类或者接口中的代码,()也可以自定义内容}

    简单理解:就是建立一个带内容的外部类或者接口的子类匿名对象。

简单内部类示例代码:

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,不可以被成员修饰符修饰
2,可以直接访问外部类中的成员,因为还持有外部类中的引用。
   但是不可以访问它所在的局部中的变量。只能访问被final修饰的局部变量。
*/
class Outer
{
	int x = 3;

	void method()
	{
		final int y = 4;//只能访问被final修饰的局部变量
		class Inner
		{
			void function()
			{
				System.out.println(y);
			}
		}
	
		new Inner().function();//调用方法
		
	}
}

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

}

匿名内部类示例:

abstract class AbsDemo//接口
{
	abstract void show();	
}
class Outer
{
	int x = 3;
	public void function()
	{
		new AbsDemo()//匿名内部类
		{
			int num = 9;
			void show()
			{
				System.out.println("num==="+num);
			}
		}.show;
	}
}
class InnerClassDemo
{
	public static void main(String[] args) 
	{
		new Outer().function();
	}
}

 

5.异常

异常的体系:

    Throwable

    |---->Error

        通常出现重大问题如:运行的类不存在或者内在溢出等,不编写针对代码对其处理

    |---->Exception

        在运行时运行出现的一些情况,可以通过try catch finally处理

Exception和Error的子类名都是以父类名作为后缀。

Throwable中的方法:

    |---->getMessage()

        获取异常信息,返回字符串。

    |---->toString()

        获取异常类名和异常信息,返回字符串。

    |---->prinStackTrace()

        获取异常类名和异常信息,以及异常出现在程序中的位置。返回值void。

    |---->printStackTrace(PrintStream s)

        通常用该方法将异常内容保存在日志文件中,以便查阅。

throws和throw:

    throws用于标识函数暴露出的异常。

    throw用于抛出异常对象。

    throws与throws的区别:

    |---->throws用在函数上,后面跟异常类名。

    |---->throw用在函数内,后面跟异常对象。

异常处理

try
{
    需要被检测的代码;
}
catch
{
    异常处理代码;
}
finally
{
一定会执行的代码;
}

finally代码块只有一种情况不执行,就是在之前执行了System.exit(0)。

自定义异常

    自定义类继承Exception或者其子类。

    通过构造函数定义异常信息。例:

class DemoException extends Exception
{
	DemoException(String message)
	{
		super(message);
	}
}

    通过throw将自定义异常抛出

异常细节

    RuntimeException以及其子类如果在函数中被throw抛出,可以不用在函数上声明。

    一个方法被覆盖时,覆盖它的方法必须抛出相同的异常或异常的子类。

    如果父类抛出多个异常,那么重写(覆盖)方法必须抛出那些异常的一个子集,不能抛出新的异常

异常的好处:

    1.将问题进行封装。

    2.将正常流程代码和问题处理代码相分离,方便于阅读。

异常的处理原则:

    1.处理方式有两种:try 或者 throws。

    2.调用到抛出异常的功能时,抛出几个,就处理几个。一个try对应多个catch。

    3.多个catch,父类的catch放到最下面。

    4.catch内,需要定义针对性的处理方式。不要简单的定义printStackTrace,输出语句。也不要不写。当捕获到的异常,本功能处理不了时,可以继续在catch中抛出。

异常示例:

class Demo
{
	int div(int a,int b)throws Exception//在功能上通过throws的关键字声明了该功能有可能会出现问题。
	{
		return a/b;
	}
}
class  ExceptionDemo1
{
	public static void main(String[] args) 
	{
		Demo d = new Demo();
		try//try语句
		{
			int x = d.div(4,0);
			System.out.println("x="+x);
		}
		catch (Exception e)//如果异常则执行catch
		{
			System.out.println(e.toString());//输出异常信息
		}
		System.out.println("over");
	}
}

 

6.包(package)

对类文件进行分类管理。

给类提供多层命名空间。

写在程序文件的第一行。

类名的全称是:包名.类名。

包也是一种封装形式。

 

classpath

    给jvm提供的一个环境变量。

    指定类或者包所在的路径。

    classpath变量值的最后有分号与无分号的区别

 

包之间的访问

    被访问的包中的类权限必须是public的。

    类中的成员权限:public或者protected

    protected是为其他包中的子类提供的一种权限

package pack;
class  PackageDemo
{
	public static void main(String[] args) 
	{
		packa.DemoA d = new packa.DemoA();
		d.show();
	}
}

 

package packa;
public class DemoA {
	public  void show()
	{
		System.out.println("demoa show run");
	}
}

 

四种权限:

public

protected

default

private

同一类中

同一包中

子类

不同包中

 

7.import,jar包,jar包的操作

import

    简化类名

    一个程序文件中只有一个package,可以有多个import。

    用来导入包中的类,不导入包中的包。

jar包

    java的压缩包

    方便项目的携带

    方便于使用,只要在classpath设置jar路径即可

    数据库驱动,SSH框架等都是以jar包体现的

jar包的操作

    通过jar.exe工具对jar的操作

    创建jar包:jar -cvf mypack.jar packa packb

    查看jar包:jar -tvf mypack.jar [>定向文件]

    解压缩:jar -xvf mypack.jar

    自定义jar包的清单文件:jar –cvfm mypack.jar mf.txt packa packb

 

 

个人总结:

本节中要理解的概念性的东西比较多,第一遍看过视频之后脑袋都是乱的,涉及到的知足点太多。这节中抽象,接口,继承,多态这几个之间的合理搭配运用是必须要掌握。重点掌握异常的获取方式和处理方式,明白自定义异常的编写方式。知识点较多,需要重复观看视频教程加深记忆与理解。面向对象中几个大块的知识点都要求必须掌握。函数的三大特征,类的各种形态,异常处理等等都是重点。

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值