黑马程序员__JAVA基础__面向对象(三)
2013-05-25 09:49
435 查看
-------android培训、java培训、java学习型技术博客、期待与您交流! ------------
抽象就是从多个事物中将共性的,本质的内容抽取出来。例如:狼和狗的共性都是犬科,犬科就是抽象出来的概念。
抽象类:
java中可以定义没有方法体的方法,该方法的具体实现由子类完成,该方法称为抽象方法,包含抽象方法的类就是抽象类。
抽象方法的由来:
多个对象都具备相同的功能,但是功能具体内容有所不同,那么在抽取过程中,只抽取了功能定义,并未抽取功能主体,那么只有功能声明,没有功能主体的方法称为抽象方法。
例如:狼和狗都有吼叫的方法,可以吼叫的内容是不一样的,所以抽取出来的犬科虽然有吼叫功能,但是并不明确吼叫的细节。
抽象类的特点:
1.抽象类和抽象方法必须用abstract关键字来修饰。
2.抽象方法只有方法声明,没有方法体,定义在抽象类中。
格式:修饰符 abstract 返回值类型 函数名(参数列表);
3.抽象类不可以被实例化,也就是不可以用new创建对象。原因如下:
抽象类是具体事物抽取出来的,本身是不具体的,没有对应的实例,例如:犬科是一个抽象的概念,真正存在的是儿狼和狗。而且抽象类即使创建了对象,调用抽象方法也没有意义。
4.抽象类通过其子类实例化,而子类需要覆盖掉抽象类中所有的抽象方法后才可以创建对象,否则子类也是抽象类。
基本抽象类代码:
继承与抽象练习:
抽象类相关问题:
1.抽象类中是否有构造函数?
答:有,抽象类是一个父类,要给子类提供一个实例的初始化。
2.抽象关键字abstrack不可以和哪些关键字共存?
答:fianl,被final修饰的类是不能有子类的,而被abstrack修饰的类一定是一个父类
private,抽象类中的私有的抽象方法是不能被子类所复写的。而抽象方法是子类必须复写的。
static,static修饰抽象方法,通过类名调用抽象方法是没有意义的。
3.抽象类中可不可以没有抽象方法?
答:抽象类中可以不定义抽象方法,这样做仅仅是不让该类建立对象。
接口中的成员修饰符是固定的:
成员常量:public static final
成员函数:public abstrack(接口中的成员都是public修饰的)
接口的出现将“多继承”通另一种形式体现出来,即“多实现”。
接口的特点:
1.接口是对外暴露的规则。
2.接口是程序的功能扩展。
3.接口可以用来多实现。
4.类与接口之间是实现关系,而且类可以 继承一个类的同时实现多个接口。
5.接口与接口之间可以有继承关系。
接口示例:
例如:动物中猫,狗
猫这个对象对应的类型是猫类型:猫 x = new 猫();
同时猫也是动物中的一种,也可以把猫称为动物:动物 y = new 猫();
动物是猫和狗具体事物中抽取出来的父类型。
父类型引用指向子类对象。
体现:父类或者接口的引用指向或者接收自己的子类对象
作用:多态的存在提高了程序的扩展性和后期可维护性
前提:1.需要存在继承或者实现关系。2.要有覆盖操作。
多态的特点
成员函数:
在编译时:要查看引用变量所属的类中是否有所调用的成员。
在运行时:要查看对象所属的类中是否有所调用的成员。
成员变量:只看引用变量所属的类。
多态示例代码:
上述代码知识点:
转型:
Animal a = new Cat();//类型提升,向上转型。
Cat c = (Cat)a;//强制将父类的引用转成子类类型,向下转型。
instanceof : 用于判断对象的类型。 对象 intanceof 类型(类类型 接口类型)
多态中成员的特点分析:
结论:
1.多态中成员函数的特点:
在编译时期:参阅引用型变量所属的类中是否有调用的方法。如果有,编译通过,如果没有编译失败。
在运行时期:参阅对象所属的类中是否有调用的方法。
成员函数在多态调用时,编译看左边,运行看右边。
2.多态中成员变量的特点:
无论编译和运行,都参考左边(引用型变量所属的类)。
3.在多态中,静态成员函数与静态变量的特点:
无论编译和运行,都参考做左边。
将一个类定义在另一个类的里面,对里面那个类就称为内部类(内置类,嵌套类)。
访问特点:内部类可以直接访问外部类中的成员,包括私有成员。而外部类要访问内部类中的成员必须要建立内部类的对象。
内部类定义在成员的位置上:
可以被private static成员修饰符修饰。被static修饰的内部类只能访问外部类中的静态成员。
内部类定义在局部位置上:
也可以直接访问外部类中的成员,同时可以访问所在局部中的局部变量,但必须是被final修饰的。
匿名内部类:就是内部类的简化写法。
前提:内部类要继承或实现一个外部类或者接口。
格式为:new 外部类名或者接口名(){覆盖类或者接口中的代码,()也可以自定义内容}
简单理解:就是建立一个带内容的外部类或者接口的子类匿名对象。
简单内部类示例代码:
内部类定义在局部示例:
匿名内部类示例:
Throwable
|---->Error
通常出现重大问题如:运行的类不存在或者内在溢出等,不编写针对代码对其处理
|---->Exception
在运行时运行出现的一些情况,可以通过try catch finally处理
Exception和Error的子类名都是以父类名作为后缀。
Throwable中的方法:
|---->getMessage()
获取异常信息,返回字符串。
|---->toString()
获取异常类名和异常信息,返回字符串。
|---->prinStackTrace()
获取异常类名和异常信息,以及异常出现在程序中的位置。返回值void。
|---->printStackTrace(PrintStream s)
通常用该方法将异常内容保存在日志文件中,以便查阅。
throws和throw:
throws用于标识函数暴露出的异常。
throw用于抛出异常对象。
throws与throws的区别:
|---->throws用在函数上,后面跟异常类名。
|---->throw用在函数内,后面跟异常对象。
异常处理
finally代码块只有一种情况不执行,就是在之前执行了System.exit(0)。
自定义异常
自定义类继承Exception或者其子类。
通过构造函数定义异常信息。例:
通过throw将自定义异常抛出
异常细节
RuntimeException以及其子类如果在函数中被throw抛出,可以不用在函数上声明。
一个方法被覆盖时,覆盖它的方法必须抛出相同的异常或异常的子类。
如果父类抛出多个异常,那么重写(覆盖)方法必须抛出那些异常的一个子集,不能抛出新的异常
异常的好处:
1.将问题进行封装。
2.将正常流程代码和问题处理代码相分离,方便于阅读。
异常的处理原则:
1.处理方式有两种:try 或者 throws。
2.调用到抛出异常的功能时,抛出几个,就处理几个。一个try对应多个catch。
3.多个catch,父类的catch放到最下面。
4.catch内,需要定义针对性的处理方式。不要简单的定义printStackTrace,输出语句。也不要不写。当捕获到的异常,本功能处理不了时,可以继续在catch中抛出。
异常示例:
给类提供多层命名空间。
写在程序文件的第一行。
类名的全称是:包名.类名。
包也是一种封装形式。
classpath
给jvm提供的一个环境变量。
指定类或者包所在的路径。
classpath变量值的最后有分号与无分号的区别
包之间的访问
被访问的包中的类权限必须是public的。
类中的成员权限:public或者protected
protected是为其他包中的子类提供的一种权限
四种权限:
简化类名
一个程序文件中只有一个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
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
个人总结:
本节中要理解的概念性的东西比较多,第一遍看过视频之后脑袋都是乱的,涉及到的知足点太多。这节中抽象,接口,继承,多态这几个之间的合理搭配运用是必须要掌握。重点掌握异常的获取方式和处理方式,明白自定义异常的编写方式。知识点较多,需要重复观看视频教程加深记忆与理解。面向对象中几个大块的知识点都要求必须掌握。函数的三大特征,类的各种形态,异常处理等等都是重点。相关文章推荐
- 黑马程序员——java基础之面向对象
- 黑马程序员——java基础知识之面向对象(二)
- 黑马程序员——java基础_面向对象
- 黑马程序员——Java基础面向对象
- 黑马程序员_Java基础_面向对象
- 黑马程序员_java基础--面向对象(1)
- 黑马程序员——Java基础---深入理解面向对象(封装继承和多态)
- 黑马程序员:java基础——OOP面向对象的特征
- 黑马程序员 Java基础知识总结-面向对象三大特征
- 黑马程序员——Java基础---面向对象(对象的初始化、对象调用成员、单例设计模式)(4)
- 黑马程序员 java 基础 毕向东 面向对象 内部类访问规则
- 黑马程序员----Java基础之面向对象(最终篇)
- 黑马程序员—java技术blog—第六篇面向对象_多态概述及基础应用
- 黑马程序员_java基础_面向对象_02
- 黑马程序员_Java基础[7]_面向对象、类、对象、匿名对象
- 黑马程序员-JAVA基础之面向对象
- 黑马程序员--Java基础--03面向对象(1)
- 黑马程序员-java学习基础04-面向对象之继续
- 黑马程序员-----java基础三(之面向对象)
- 黑马程序员---java基础---2面向对象