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

黑马程序员——Java基础——面对对象

2014-12-13 14:54 204 查看
------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

面向对象

一、面对对象的特点 :

1.将复杂的事情简单化

2.面性对象将以前的过程中的执行者变成了指挥者。

3.面向对象这种思想是符合现在人们思考习惯的一种思想

过程和对象在我们程序中是如何体现的呢?

过程就是函数,对象时将函数等一些内容进行了封装。

对象、类有什么区别?

类是对象的抽象,对象是类的具体表现形式,类就是一类事物,而对象就是一个事物,一类事物中包含若干的事物(而这其中的具体的事物就是对象)。

比如:类就是车的模型,对象就是具体的车,车可能有红色,可能有蓝色,对象之间是有差异的。

面向对象和面向过程有什么区别?

面向过程强调执行的动作和执行的过程,而面向对象强调结果。

类就是:对现实生活中事物的描述。
对象:就是这类事物,实实在在存在个体

注:

在Java的开发过程,其实就是不断的创建对象,使用对象,指挥对象做事情。设计的过程,其实就是在管理和维护对象之间的关系。

二、面向对象的三个特性:

1.封装

1.1
基本概念 


封装(encapsulation)是面向对象三大特征之一,它是指将对象的状态信心隐藏在对象的内部,不允许外部直接进行访问,而是通过该类提供的方法来实现对内部信息的操作和访问。封装的作用如下:

a)、隐藏类的实现细节。

b)、让使用者只能通过实现预定的方法来访问数据,从而可以在方法里添加逻辑控制,限制对类成员的不合理访问

c)、可以进行检查,从而有利于保证对象信息的完整性。

d)、便于修改,提高代码的可维护性

1.2
具体实现规律

为了实现良好的封装,需要从以下两个方面进行考虑:

a)、将队形的成员变量和实现细节进行隐藏,不允许外部进行直接访问。

b)、把方法暴露出来,让方法来控制对这些成员变量进行安全的访问和操作。

因此封装实际上有两个方面的含义:把该隐藏的隐藏起来,把该暴露的暴露出来。这两个方面都需要通过java的访问控制符去实现。

下面程序便演示了封装的表现形式:


class Person{

private String name;

private int age;

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public int getAge() {

return age;

}

public void setAge(int age) {

this.age = age;

}

}


2.继承

继承是面向对象的三大特征之一,也是实现软件复用的重要手段。Java的继承只允许单继承,但是运行多实现。

2.1
继承特点:


a)、提高了代码的复用性

b)、让类与类之间产生了关系,有了这个关系,才有了多态的特性。必须是类与类之间有所属关系才可以使用继承。

2.2
继承体系的使用规律:


查阅父类的功能,建立子类的实例。

2.3
原因:


因为有可能父类不能创建对象

创建子类对象可以使用更多功能,包括基本的也包括特有的。

2.4
子父类中变量特点

父类的成员变量私有化之后,子类依然继承,但不能直接访问。
如果子类中出现非私有的同名成员变量时,自类要访问本类中的变量用 this ,要访问父类中的同名变量,用super

2.5
覆盖

当子类中出现和父类一模一样的函数时,当子类对象调用该函数,会运行子类函数的内容,如同父类的函数被覆盖一样。这就是重写。
当子类继承了父类,沿袭了父类的功能,到子类中,但是子类虽然具备该功能,但是功能的内容却和父类不一样,这是没有必要定义新功能,而是使用覆盖特性,保留父类的功能定义,并重写功能内容。这是用
super。
注意:
子类覆盖父类,必须保证子类权限大于等于父类权限,才能重写
静态只能访问静态


2.6
子父类中构造函数特点:

在对子类对象进行初始化时,父类的构造函数也会运行。子类只会隐式调用父类的空参构造函数。

2.7
子类一定会访问父类中的构造函数原因:


因为父类中的数据子类可以直接获取,所以子类对象在建立时,需要先查看父类是如何对这些数据进行初始化的。所以子类在对象初始化时,要先访问一下父类中的构造函数。如果要访问父类中指定的构造函数,可以通过手动定义super语句的方式来指定。

2.8
其他


子类的所有构造函数,默认都会访问父类中无参的构造函数,因为子类的每一个构造函数内的第一行都有一句隐式super();

当父类中没有空参数的构造函数时,子类必须手动通过super语句形式来指定要访问父类中的构造函数。

当然子类的构造函数第一行也可以手动指定this语句来访问本类中的构造函数,子类中至少会有一个构造函数会访问父类中的构造函数。

//定义一个人父类
class Person
{
//名字和年龄是人的共有属性
String name;
int age;

//在构造函数中对名字和年龄进行初始化
Person(String name,int age)
{
this.name=name;
this.age=age;
System.out.println(name+"  "+age);
}
//人都具有睡觉的功能
void sleep()
{
System.out.println("sleep");
}
}
//定义一个学生,继承人,作为子类
class Student extends Person
{
Student(String name,int age)
{
super(name,age);	//super关键字表示父类,因为姓名和年龄在父类中进行了初始化动作,在这里可以直接调用
}
//学生具有特有的功能,学习
void study()
{
System.out.println("study");
}

}

class Demo
{
public static void main(String[] args)
{
Student s=new Student("zhangsan",20);
System.out.println(s.name="wangwu");
s.sleep();
s.study();
}
}


3.多态

Java引用变量有两种类型,一个是编译时类型,一个是运行时类型。编译时类型有声明该变量时使用的类型决定,运行时类型由实际赋给该变量的对象决定。如果编译时类型和运行时类型不一致,就可能出现所谓的多态(polymorphism)。

3.1
多态的理解

可以理解为事物存在的多种体现形态。表现为父类的引用指向子类的对象。

3.2
多态的体现


父类的引用指向子类的对象,父类的引用接收子类的对象。

3.3多态的前提

类与类之间必须是继承或者实现的关系。通常还有一个前提
就是覆盖

3.4
多态的好处


大大的提高了程序的扩展性

3.5
多态的弊端


提高了扩展性,但是只能使用父类的引用访问父类中的成员。

3.6
多态的应用


定义好工具类,即将共同行为封装在一个类中。

        对类型进行抽取,---->多态的产生。

        操作同一父类型,对其中的子类型均可操作

3.7
多态中成员的特点

a)、多态中非静态成员函数的特点

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

如:在上面的示例中,如果用a.catchMouse();编译就会报错。这时只能通过强转,向下转型后,可以使用子类的特有功能。

        在运行时期:参阅对象所属的类中是否有调用的方法。这就是说,如果父类中有一个非抽象的方法,而子类继承后又将其复写了,在多态运行时,父类的引用调用这个同名函数时,被运行的将是父类中的方法。

        简单总结就是:成员函数在多态调用时,编译看左边,运行看右边。

b)、多态中成员变量的特点

        无论编译和运行,都参考左边(引用变量所属的类)。如:多态中的父类引用调用成员变量时,如果父类和子类有同名的成员变量,那么被调用的是父类中的成员变量。

c)、多态中静态成员函数的特点

        无论编译和运行,都参考左边。也就是父类引用在调用静态同名函数时,被调用的是父类中的静态函数。这是因为,当类一被加载,静态函数就随类绑定在了内存中。此时,不需要创建对象,就可以使用类名直接调用。同时,父类中的静态成员函数一般是不被复写的。

类在方法区中的分配:分为静态区和非静态区,而关键字this和super在非静态区。

3.8 如何使用子类特有方法

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

a.eat();//父类的共有方法。
如果要调用cat的特有方法的时候 ,就必须将父类的引用转成子类的类型,但是不能将父类对象转成子类类型,转换的是父类的引用,(就是父类的变量)

 
Cat c=(Cat)a;

c.catchmouse();//子类的特有方法。
//父类————动物
abstract class Animal
{
public abstract void eat();

}

//子类————猫
class Cat extends Animal
{
//复写父类中的抽象功能
public void eat()
{
System.out.println("吃鱼");
}

//Cat特有的功能
public static void catchMouse()
{
System.out.println("抓老鼠");
}
}

class Demo
{
public static void main(String[] args)
{
Animal a = new Cat();
a.eat();
Cat c = (Cat)a;
c.catchMouse();
}
}


二、抽象类(abstract)    

当编写一个类时,时常会为该类定义一些方法,这些方法的使用用以描述该类的行为方式,那么这些方法都有具体的方法体。但是在某些情况下,某个父类只是知道子类应该包含怎样的方法,但是无法精确的知道这些子类是如何实现这些方法,例如定义一个GetTime类,该类提供了一个计算某一段程序运行时间的gettime方法,但是无法知道具体运行什么方法体,这时就需要使用抽象方法来实现了。

抽象类概念

当多个类中出现相同功能,但是功能主体不同,这时候可以进行向上抽取,只抽取功能定义,而不抽取功能主体。分析事物不确定时,就抽象。

1.特点:

     1.抽象方法只能定义在抽象类中。

     2.抽象方法和抽象类必须被abstract修饰

     3.抽象类不可以用new 创建对象,因为创建对象没有意义

     4.抽象类中的抽象方法要被使用,必须由子类复写抽象方法后,建立子类对象调用

     5.如果子类只覆盖了部分抽象方法,那么该子类还是一个抽象类。如果不想子类是抽象类必须,复写父类抽象类中的全部抽象方法。

特殊

抽象类中可以不定义抽象方法,这样做仅仅是为了避免建立本类对象

2.什么时候使用抽象:

抽象类和一般类没有太大的区别,当事物出现不确定的功能,需要明确指出,但是无法定义主体,通过抽象方法来表示。

抽象类比一般类多了个抽象方法,抽象类不可以实例化,抽象类中还可以定义非抽象方法,目的是不让该类建立对象。

3.抽象类成员

抽象类可以包含 普通方法、
成员变量、 构造方法。

4.抽象格式特点

在需要抽象的方法上用abstract进行修饰,同时该方法没有方法体,结尾';'结尾。

5.应用:

假如我们在开发一个系统时需要对员工进行建模,员工包含 3 个属性:
姓名、工号以及工资。经理也是员工,除了含有员工的属性外,另为还有一个
奖金属性。请使用继承的思想设计出员工类和经理类。要求类中提供必要的方
法进行属性访问。

员工类:name id pay

经理类:继承了员工,并有自己特有的bonus。

*/

//员工类,也是父类
abstract 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");
}
}

class  AbstractDemo
{
public static void main(String[] args)
{
new Manager("manager","001",10000,2000).work();
new Pro("pro","020",5000).work();
}
}


注意事项:

     不能与 final 一起使用:抽象是用来继承的所以不可以与final同时使用。

     不能与private一起使用: 抽象类中的私有的抽象方法,不被子类所知,就无法被复写。而抽象方法出现的就是需要被复写。

     不能与 static 一起使用:如果static可以修饰抽象方法,那么连对象都省了,直接类名调用就可以了。可是抽象方法运行没意义。

     抽象类该怎样描述事物就怎么描述,只是有一些内容"看不懂",所以可以有包含成员变量与方法,构造方法。

     如果一个类中存在抽象方法,那么该类一定要用abstract修饰(该类一点是抽象类)

三、接口(interface)

     由于电脑买的比较早,硬盘的容量很小,随着时间的推移慢慢的感觉到存储容量的压力,但是电脑为我提供了一个USB接口,由于USB接口的存在,我买一个移动硬盘就很好的解决了硬盘容量不足的问题,假设如果没有USB接口要想解决这个问题就需要更换硬盘,或者换电脑其弊端大家很容易就明白了。这里我们说的接口和要介绍的程序接口道理是相通的。

1.接口概念

     接口定义了一系列规范,想要实现某一个功能就必须遵守该规范,也就是说是
要想实现某一个接口,就must be按照使用接口的规范(读者反馈,谢谢)。

     初期理解,可以认为是一个特殊的抽象类当抽象类中的方法都是抽象的,那么该类可以通过接口的形式来表示。

2.特点

1,接口中可以定义:常量,抽象方法。

2,接口中的成员都有固定修饰符:

           常量:public static final

           方法:public abstract

记住:接口中的成员都是public的。

3,接口不可以创建对象

3.接口作用

1,接口是对外暴露的规则

2,接口是程序的功能扩展

3,接口的作用主要是为了统一访问

4.什么时候使用接口

当使用一个函数(暂且说是函数吧)时,但是函数的主体不确定,只是定义该方法的规范比如返回值,参数列表时,这是就应该考虑使用接口区定义。

5.接口的成员

常量,抽象方法。

6.接口格式特点

在生命一个类是接口时不再吃用class
而是使用 interface去定义。

7.注意事项

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

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

接口可以被类多实现,也是对多继承不支持的转换形式。java支持多实现。

接口之间关系为继承,需要特别声明的是接口之间允许使用多继承。所以从这个角度来说 java支持多继承。

8.应用实例

   
//抽象学生类
abstract class Student
{
//抽象的学习方法
abstract void study();
//共性内容非抽象的睡觉方法
void sleep()
{
System.out.println("sleep");
}
}

//接口,吸烟
interface Smoking
{
void smoke();
}

//Zhangsan这个对象继承学生类,实现吸烟接口
class Zhangsan extends Student implements Smoking
{
//复写学习方法
void study()
{
System.out.println("Zhangsan_study");
}

//复写吸烟方法
public void smoke()
{
System.out.println("Zhangsan_smoking");
}
}

//Lisi是好学生,不吸烟
class Lisi extends Student
{
//复写学习方法
void study()
{
System.out.println("Lisi_study");
}
}

class InterfaceDemo
{
public static void main(String[] args)
{
Zhangsan z = new Zhangsan();
z.study();
z.smoke();
new Lisi().study();
}
}


抽象与接口区别

   
抽象:


         1、抽象类是可以有私有方法或私有变量的,实现抽象类可以有选择地重写需要用到的方法,

            但是必须实现里面所有的抽象方法。

         2、抽象类在 Java 语言中表示的是一种继承关系,一个类只能使用一次继承关系。

         3、抽象类中可以有自己的数据成员,也可以有非abstarct的成员方法。

         4、抽象类和接口所反映出的设计理念不同。其实abstract class表示的是"is-a"关系

         5、抽象类中的变量默认是 friendly 型,其值可以在子类中重新定义,也可以重新赋值。

   
接口:


         1、接口是公开(public)的,里面不能有私有的方法或变量,是用于让别人使用的,

            实现接口的一定要实现接口里定义的所有方法。

         2、一个类却可以实现多个interface(java中实现多重继承的方法之一)。

             而在接口中,只能够有静态的不能被修改的数据成员(也就是必须是 static
final的,

         3、不过在 interface中一般不定义数据成员),而且所有的成员方法都是抽象的。

         4、interface表示的是"like-a"关系。(组合是"has a"关系)

         5、接口中定义的变量默认是public static final 型,且必须给其初值,

            所以实现类中不能重新定义,也不能改变其值。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: