面向对象

来源:互联网 发布:sql截掉字符串 编辑:程序博客网 时间:2024/06/01 14:54

第五天:
面向对象:
面向对象是相对面向过程而言
面向对象和面向过程都是一种思想
面向过程
强调的是功能行为
面向对象
将功能封装进对象,强调具备了功能的对象。
面向对象是基于面向过程的。
特点:
是一种符合人们思考习惯的思想
可以将复杂的事情简单化
将程序员从执行者转换成了指挥者
完成需求时:
先要去找具有所需的功能的对象来用。
如果该对象不存在,那么创建一个具有所需功能的对象。
这样简化开发并提高复用。
面向对象开发,设计。特征:
开发的过程:其实就是不断的创建对象,使用对象,指挥对象做事情。
设计的过程:其实就是在管理和维护对象之间的关系。
面向对象的特征:
封装(encapsulation)
继承(inheritance)
多态(polymorphism)
实例理解:火车司机停火车:司机给火车发出停车指令,车接到指令,用自身的停车方法停车(这个方法列车自己清楚)

类与对象的关系:
理解:类就好比图纸,对象就是按图纸创造出来的实例,这个实例可以对其进行修改属性。
使用计算机语言就是不断的在描述现实生活中的事物。
java中描述事物通过类的形式体现,类是具体事物的抽象,概念上的定义。
        对象即是该类事物实实在在存在的个体。

匿名对象与引用对象:

class Car//类:图纸{//描述颜色String color = "红色";//描述轮胎数int num = 4;//运行行为。void run(){System.out.println(color+".."+num);}}class  CarDemo{public static void main(String[] args) {Car c = new Car();//根据图纸在堆内存中建立对象c.run();c.num = 4;//如果对一个对象进行多个成员调用,必须给这个对象起个名字。c.color = "blue";//需求:将已有车的颜色改成蓝色。指挥该对象做使用。在java指挥方式是:对象.对象成员new Car().run();//匿名对象使用方式一:当对对象的方法只调用一次时,可以用匿名对象来完成,这样写比较简化。show(new Car);//匿名对象使用方式二:可以将匿名对象作为实际参数进行传递。}public static void show(Car c)//修改对象属性方法。{c.num = 3;c.color = "black";c.run();}}}


匿名对象和对象在内存中传递过程区别的图解:

 

 

 

成员变量与局部变量的区别:
成员变量:
成员变量定义在类中,在整个类中都可以被访问。
成员变量随着对象的建立而建立,存在于对象所在的堆内存中。
成员变量有默认初始化值。
局部变量:
局部变量只定义在局部范围内,如:函数内,语句内等。
局部变量存在于栈内存中。
作用的范围结束,变量空间会自动释放。
局部变量没有默认初始化值。

封装:
封装:是指隐藏对象的属性和实现细节,仅对外提供公共访问方式。
好处:
将变化隔离。
便于使用。
提高重用性。
提高安全性。
封装原则:
将不需要对外提供的内容都隐藏起来。
把属性都隐藏,提供公共方法对其访问。
private关键字:
是一个权限修饰符。
用于修饰成员(成员变量和成员函数)
被私有化的成员只在本类中有效。
常用之一:
将成员变量私有化,对外提供对应的set ,get方法对其进行访问。提高对数据访问的安全性


构造函数:
特点:
函数名与类名相同
不用定义返回值类型
不可以写return语句
作用:
给对象进行初始化。
构造代码块。
作用:给对象进行初始化。
对象一建立就运行,而且优先于构造函数执行。
构造代码块和构造函数的区别:
 构造代码块是给所有对象进行统一初始化,
 而构造函数是给对应的对象初始化。

 构造代码快中定义的是不同对象共性的初始化内容

this关键字
特点:this代表其所在函数所属对象的引用。
换言之:this代本类对象的引用。

什么时候使用this关键字呢?
当在函数内需要用到调用该函数的对象时,就用this。
例程。

私有,构造函数,构造代码块代码:

class Person{private String name;private int age;//私有成员属性{cry();}//构造代码块Person()//不带参数的构造函数{System.out.println("A: name="+name+",,age="+age);}Person(String n)//带参数的构造函数{name = n;System.out.println("B: name="+name+",,age="+age);//cry();}public void setAge(int a)//设置私有属性{if(a>0 && a<130){age = a;speak();}elseSystem.out.println("feifa age");}public int getAge()//获取私有属性{return age;}private void speak(){System.out.println("age="+age);}public void cry(){System.out.println("cry......");}}


 

第六天:
static关键字
用于修饰成员(成员变量和成员函数)
被修饰后的成员具备以下特点:
随着类的加载而加载
优先于对象存在
被所有对象所共享
可以直接被类名调用
使用注意
静态方法只能访问静态成员
静态方法中不可以写this,super关键字
主函数是静态的

static特点:
1,随着类的加载而加载。
   也就说:静态会随着类的消失而消失。说明它的生命周期最长。
2,优先于的对象存在
明确一点:静态是先存在。对象是后存在的。
3,被所有对象所共享
4,可以直接被类名所调用。

实例变量(成员变量)和类变量(静态成员变量)的区别:
1,存放位置。
 类变量随着类的加载而存在于方法区中。
 实例变量随着对象的建立而存在于堆内存中。
2,生命周期:
 类变量生命周期最长,随着类的消失而消失。
 实例变量生命周期随着对象的消失而消失。

静态使用注意事项:
1,静态方法只能访问静态成员。
 非静态方法既可以访问静态也可以访问非静态。
2,静态方法中不可以定义this,super关键字。
 因为静态优先于对象存在。所以静态方法中不可以出现this。
3,主函数是静态的。
 
静态有利有弊
利处:对对象的共享数据进行单独空间的存储,节省空间。没有必要每一个对象中都存储一份。
 可以直接被类名调用。
弊端:生命周期过长。
   访问出现局限性。(静态虽好,只能访问静态。)

什么使用静态?
要从两方面下手:
因为静态修饰的内容有成员变量和函数。

什么时候定义静态变量(类变量)呢?
当对象中出现共享数据时,该数据被静态所修饰。
对象中的特有数据要定义成非静态存在于堆内存中。

什么时候定义静态函数呢?
当功能内部没有访问到肺静态数据(对象的特有数据),
那么该功能可以定义成静态的。

静态的应用:工具类

静态代码块:
给类初始化的
格式
static
{
 静态代码块中的执行语句
}
特点:随着类的加载而执行。只执行一次。

构造函数,构造代码块,静态代码块的执行顺序。

class  StaticCodeDemo{public static void main(String[] args) {new StaticCode(4);//打印结果 a c d}}class StaticCode{StaticCode()//随对象的创建而执行{System.out.println("b");//(构造函数)给没有参数对象初始化的}static//随类的加载而执行{System.out.println("a");//(静态代码块)给类初始化的}StaticCode(int x)//随对象的创建而执行{System.out.println("d");//(构造函数)给对应对象初始化的}{System.out.println("c");//(构造代码块)给对象初始化的}//随对象的创建而执行,优先于构造函数先执行。}


 

main主函数:
public static void main(String[] args)

主函数:是一个特殊的函数。作为程序的入口,可以被jvm调用。

主函数的定义:
public:代表着该函数访问权限是最大的。
static:代表主函数随着类的加载就已经存在了。
void:主函数没有具体的返回值。
main:不是关键字,但是是一个特殊的单词,可以被jvm识别。
(String[] arr):函数的参数,参数类型是一个数组,该数组中的元素是字符串。字符串类型的数组。
主函数是固定格式的:jvm识别。
jvm在调用主函数时,传入的是new String[0];


对象的初始化过程:

class Person{private Person(){}private String name = "hah";private int age;private static  String country = "cn";Person(String name,int age){this.name = name;this.age = age;}{System.out.println(name+".."+age);}public void setName(String name){this.name = name;}public void speak(){System.out.println(this.name+"..."+this.age);}public static void  showCountry(){System.out.println("country="+Person.country);Person.method();}public static void method(){System.out.println("method run");}}class  PersonDemo{public static void main(String[] args) {Person p = new Person("zhangsan",20);p.setName("lisi");new Person();}}/*Person p = new Person("zhangsan",20);该句话都做了什么事情?1,因为new用到了Person.class.所以会先找到Person.class文件并加载到内存中。2,执行该类中的static代码块,如果有的话,给Person.class类进行初始化。3,在堆内存中开辟空间,分配内存地址。4,在堆内存中建立对象的特有属性。并进行默认初始化。5,对属性进行显示初始化。6,对对象进行构造代码块初始化。7,对对象进行对应的构造函数初始化。8,将内存地址付给栈内存中的p变量。*/


 

设计模式:解决某一类问题最行之有效的方法。
java中23种设计模式:
单例设计模式:解决一个类在内存只存在一个对象。

想要保证对象唯一。
1,为了避免其他程序过多建立该类对象。先禁止其他程序建立该类对象
2,还为了让其他程序可以访问到该类对象,只好在本类中,自定义一个对象。
3,为了方便其他程序对自定义对象的访问,可以对外提供一些访问方式。

这三部怎么用代码体现呢?
1,将构造函数私有化。
2,在类中创建一个本类对象。
3,提供一个方法可以获取到该对象。

对于事物该怎么描述,还怎么描述。
当需要将该事物的对象保证在内存中唯一时,就将以上的三步加上即可。

饿汉式:开发用

class Single{private  Single(){}private static Single s = new Single();public static  Single getInstance(){return s;}}


懒汉式:

class Single{private static Single s = null;private Single(){}public static Single getInstance(){if(s==null)//双重判断,可以提高点效率{synchronized(Single.class)//静态的锁为Single.class,要锁住,不然有可能会是对象不是同一个{if(s==null)s = new Single();}}return s;}}


 

第七天
继承:
多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继那个类即可。
多个类可以称为子类,单独这个类称为父类或者超类。
子类可以直接访问父类中的非私有的属性和行为。
通过 extends 关键字让类与类之间产生继承关系。
class SubDemo extends Demo{}
继承的出现提高了代码的复用性。
继承的出现让类与类之间产生了关系,提供了多态的前提
继承特点:
Java只支持单继承,不支持多继承。
Java支持多层继承(继承体系)
定义继承需要注意:
不要仅为了获取其他类中某个功能而去继承
类与类之间要有所属( " is a " )关系,xx1是xx2的一种。

super关键字
super和this的用法相像
this代表本类对象的引用
super代表父类的内存空间的标识。
当子父类出现同名成员时,可以用super进行区分
子类要调用父类构造函数时,可以使用super语句。

继承的覆盖:
子类中出现与父类一模一样的方法时,会出现覆盖操作,也称为重写或者复写。
父类中的私有方法不可以被覆盖。
在子类覆盖方法中,继续使用被覆盖的方法可以通过super.函数名获取。
覆盖注意事项:
覆盖时,子类方法权限一定要大于等于父类方法权限
静态只能覆盖静态。
覆盖的应用:
当子类需要父类的功能,而功能主体子类有自己特有内容时,可以复写父类中的方法,
这样,即沿袭了父类的功能,又定义了子类特有的内容
重载:只看同名函数的参数列表。
重写:子父类方法要一模一样。

final关键字
final可以修饰类,方法,变量。
final修饰的类不可以被继承。
final修饰的方法不可以被覆盖。
final修饰的变量是一个常量。只能被赋值一次。
内部类只能访问被final修饰的局部变量。

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

注意:super语句一定定义在子类构造函数的第一行。

 

子类的实例化过程

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

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

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

class Fu //extends Object{int num ;Fu(){//super();隐式的语句num= 60;System.out.println("fu run");}Fu(int  x){System.out.println("fu ...."+x);}}class Zi extends Fu{Zi(){super();  //隐式的语句//super(4);System.out.println("zi run");}Zi(int x){this();//这样,第一行没super//super();//super(3);System.out.println("zi..."+x);}}

抽象类:
抽象定义:
抽象就是从多个事物中将共性的,本质的内容抽取出来。
例如:狼和狗共性都是犬科,犬科就是抽象出来的概念。
抽象类的特点:
1,抽象方法一定在抽象类中。
2,抽象方法和抽象类都必须被abstract关键字修饰。
3,抽象类不可以用new创建对象。因为调用抽象方法没意义。
4,抽象类中的抽象方法要被使用,必须由子类复写起所有的抽象方法后,建立子类对象调用。
 如果子类只覆盖了部分抽象方法,那么该子类还是一个抽象类。

抽象类和一般类没有太大的不同。
该如何描述事物,就如何描述事物,只不过,该事物出现了一些看不懂的东西。
这些不确定的部分,也是该事物的功能,需要明确出现。但是无法定义主体。
通过抽象方法来表示。

抽象类比一般类多个了抽象函数。就是在类中可以定义抽象方法。
抽象类不可以实例化。

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

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

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

abstract class Student{abstract  void study();//abstract void study1();void sleep(){System.out.println("躺着");}}


什么是模版方法呢?
在定义功能时,功能的一部分是确定的,但是有一部分是不确定,而确定的部分在使用不确定的部分,
那么这时就将不确定的部分暴露出去。由该类的子类去完成。

abstract class GetTime{public final void getTime()//模板方法{long start = System.currentTimeMillis();runcode();long end = System.currentTimeMillis();System.out.println("毫秒:"+(end-start));}public abstract void runcode();}class SubTime extends GetTime{public void runcode(){for(int x=0; x<4000; x++){System.out.print(x);}}}

 

接口:
初期理解,可以认为是一个特殊的抽象类
 当抽象类中的方法都是抽象的,那么该类可以通过接口的形式来表示。
class用于定义类
interface 用于定义接口。
格式:
    interface 接口名{}

接口定义时,格式特点:
1,接口中常见定义:常量,抽象方法。
2,接口中的成员都有固定修饰符。
 常量:public static final
 方法:public abstract
记住:接口中的成员都是public的。

接口是不可以创建对象的,因为有抽象方法。
需要被子类实现,子类对接口中的抽象方法全都覆盖后,子类才可以实例化。
否则子类是一个抽象类。
接口可以被类多实现,也是对多继承不支持的转换形式。java支持多实现。

接口的特点:
接口是对外暴露的规则。
接口是程序的功能扩展。
接口的出现降低耦合性。
接口可以用来多实现。
类与接口之间是实现关系,而且类可以继承一个类的同时实现多个接口。
接口与接口之间可以有继承关系。

接口与抽象类
共  性: 都是不断抽取出来的抽象的概念
区别 1: 抽象类体现继承关系,一个类只能单继承
   接口体现实现关系,一个类可以多实现
区别 2: 抽象类是继承,是 "is a "关系
   接口是实现,是 "like a"关系
区别 3: 抽象类中可以定义非抽象方法,供子类直接使用
   接口的方法都是抽象,接口中的成员都有固定修饰符

第八天
多态:
定义:某一类事物的多种存在形态。
格式:
动物  y = new 猫();//动物为父类,类型提升。 向上转型
多态的强转:
动物  y = new 猫();
猫 x =(猫)y//类型强转, 向下转型
//千万不要出现这样的操作,就是将父类对象转成子类类型。
//我们能转换的是父类应用指向了自己的子类对象时,该应用可以被提升,也可以被强制转换。
//多态自始至终都是子类对象在做着变化。
注意:只能将子类强转。

程序中体现:
父类或者接口的引用指向或者接收自己的子类对象。
好处和作用:
多态的存在提高了程序的扩展性和后期可维护性
弊端:(局限性)
虽然提高了扩展性,但是只能使用父类的引用访问父类中的成员,子类的特有方法无法使用。

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

在多态中成员函数的特点:
在编译时期:参阅引用型变量所属的类中是否有调用的方法。如果有,编译通过,如果没有编译失败。
在运行时期:参阅对象所属的类中是否有调用的方法。
简单总结就是:成员函数在多态调用时,编译看左边,运行看右边。

在多态中,成员变量的特点:
无论编译和运行,都参考左边(引用型变量所属的类)。

在多态中,静态成员函数的特点:
无论编译和运行,都参考做左边。

多态在接口中的应用

/*需求:电脑运行实例,电脑运行基于主板。*/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());}}

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

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

内部类的位置:
内部类定义在成员位置上
可以被private static成员修饰符修饰。
被static修饰的内部类只能访问外部类中的静态成员。

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

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

匿名内部类(一种特殊的局部内部类):
就是内部类的简化写法。
前提:
内部类可以继承或实现一个外部类或者接口。
格式为:
new 外部类名或者接口名(){覆盖类或者接口中的代码,(也可以自定义内容。)}

在使用匿名内部类时,要记住以下几个原则:
 匿名内部类不能有构造方法。
 匿名内部类不能定义任何静态成员、方法和类
 匿名内部类不能是public,protected,private,static。
 只能创建匿名内部类的一个实例。
 一个匿名内部类一定是在new的后面,用其隐含实现一个接口或实现一个类。
注意: 因匿名内部类为局部内部类,所以局部内部类的所有限制都对其生效。
实例:

class nimingneibulei{public static void main(String[] args) {System.out.println("Hello World!");}}abstract class AbsDemo{abstract void show();}class Outer{int x =3;/*class Inner extends AbsDemo{void show(){System.out.println("show"+Outer.this.x);//省略了Outer.this}}*/public void function(){/*class Inner extends AbsDemo{void show(){System.out.println("show"+Outer.this.x);//省略了Outer.this}}*///new Inner().show();//下面就是匿名内部类对象。即继承了抽象类的匿名内部类对象。new AbsDemo(){void show(){System.out.println("x==="+x);//上面两个绿色部分可以写成这样的匿名内部类对象}}.show();}}

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

 

包(package)
对类文件进行分类管理。
给类提供多层命名空间。
写在程序文件的第一行。
类名的全称的是  包名.类名。
包也是一种封装形式。
javac -d . 类名.java//-d自动生成包名(win下)
java 包名.类名//运行包下的clss文件

包之间的访问:
被访问的包中的类权限必须是public的。
类中的成员权限:public或者protected
protected是为其他包中的子类提供的一种权限

四种权限
                public protected default private
同一类中 √               √            √        √
同一包中 √              √            √ 
子类         √             √  
不同包中 √  

import(导入)
简化类名。
一个程序文件中只有一个package,可以有多个import。
用来导包中的类,不导入包中的包。
通常写import  mypack.Demo;

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





 

原创粉丝点击