您的位置:首页 > 职场人生

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

2013-05-25 09:49 435 查看
-------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

个人总结:

本节中要理解的概念性的东西比较多,第一遍看过视频之后脑袋都是乱的,涉及到的知足点太多。这节中抽象,接口,继承,多态这几个之间的合理搭配运用是必须要掌握。重点掌握异常的获取方式和处理方式,明白自定义异常的编写方式。知识点较多,需要重复观看视频教程加深记忆与理解。面向对象中几个大块的知识点都要求必须掌握。函数的三大特征,类的各种形态,异常处理等等都是重点。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: