面向对象

来源:互联网 发布:js字符串类型 编辑:程序博客网 时间:2024/06/05 11:19

概述:面向对象(Object-Oriented,简称OO)是一种对现实世界理解和抽象的方法计算机编程技术面向对象的三大特征:

封装(Encapsulation)

继承(Inheritance)

多态(Polymorphism)

一、访问修饰符,类,关键字和构造方法:

1)private:类访问权限:本类内部可以访问,不能继承到子类;

2)default:什么都不写,包访问权限:本类内部可以访问,同包其他类也可以访问,同包可继承;

3)protected:子类访问权限:本类内部可以访问,不同包的子类也可以访问,同包其他类也可以访问,能继承到子类;

4)public:公共访问权限:任何地方都可以访问,能继承到子类;

5)类(class):是Java 语言的最小编程单位,也是设计和实现Java 程序的基础。类是一组事物共有特征和功能的描述。类的概念是抽象的,类似于建筑设计中的图纸,是对于现实需要代表的具体内容的抽象。类只包含框架结构,而不包含具体的数据。所以类代表的是总体,而不代表某个特定的个体。

类的对象包含:属性和方法。

6)static 关键字:一般都用static静态方法可以不用初始化,就能够直接调用。

Static常用语静态代码块编写,特点,随着类的加载而执行,只执行一次,优先于主函数

注意:

1、静态方法只能访问静态成员;

2、而非静态成员可以访问静态成员

3、静态方法中不可以使用this,super关键字

7)this 关键字:this 表示当前对象。帮助理解:当在一个类中要明确指出使用对象自己的变量或函数时就应该加上 this 引用。

8)void 关键字:用来声明无返回值的函数。

9)final 关键字:最后的,最终的。

1、final类,final类不能被继承,因此final类的成员方法没有机会被覆盖,默认都是final的。在设计类时候,如果这个类不需要有子类,类的实现细节不允许改变,并且确信这个类不会再被扩展,那么就设计为final类。 final方法不能被子类的方法覆盖,但可以被继承。

2、final方法,如果一个类不允许其子类覆盖某个方法,则可以把这个方法声明为final方法。

使用final方法的原因有二:

第一、把方法锁定,防止任何继承类修改它的意义和实现。

第二、高效。编译器在遇到调用final方法时候会转入内嵌机制,大大提高执行效率。

3、final变量(常量),用final修饰的成员变量表示常量,只能被赋值一次,赋值后值无法改变!

final修饰的变量有三种:静态变量、实例变量和局部变量,分别表示三种类型的常量。

10)super 关键字:常用于子父类方法中的子类,当子类继承父类的时候,要调用父类的方法,成员变量时,就要用到 super,用法:super.方法名。注意,当父类中的成员被私有化时,子类无法访问到父类的私有化变量,方法。只能通过父类提供的公共的构造方法访问。

11)构造方法:是用来构造类的实例,因为每一个类都有一个默认的无参数的构造方法,这个构造方法是用于给对象初始化new一次,用一次如果构造方法被私有化,则这个构造方法不能被初始化

私有化:是封装的一种表现形式。是为了控制传入的数据,和操作,提高代码健壮性。

构造方法一开始就运行,给对象初始化

一般方法可以被改对象多次使用

Person p = new Person("zhangsan",20);

这句话做了什么事情?

1、因为new用到了Person.class,所以会找到Person.class文件,并加载到内存中。

2、执行该类中的static静态代码块,如果有的话,给Person.class类进行初始化。

3、在堆内存中开辟内存空间,并确定分配内存地址

4、在堆内存中建立对象的特有属性,并进行默认初始化。

5、对属性进行显示初始化。

6、对对象进行构造代码块初始化。

7、对对象进行对应的构造方法初始化。

将对象地址付给栈内存中的p变量。

 

二、面向对象的封装:

是指隐藏对象的属性和实现细节,仅对外提供公共访方式。

1)封装的好处:

 1、将变化隔离

 2、便于使用

 3、提高重用性

 4、提高安全性

2)封装原则:

 1、将不需要对外提供的内容都隐藏起来

 2、把属性都隐藏起来,提供公共访问方法对其访问。

3)私有化也是封装的一种表现形式。

4)demo:对私有属性提供对外的公共的get 和set 方法。

public class Person {private String name;//私有化,是为了控制传入的数据,和操作,提高健壮性。private int age;<span style="white-space:pre"></span>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;}}

三、面向对象的继承:

新的实例要在原有类上的扩展,就是继承原有类的功能外还可以扩展需要的功能。

继承的好处:

1、提高代码的复用性。

 2、让类与类之间产生了关系。有了这个关系才有了多态性。

 3、java 支持多实现

1)继承的原则:

java 语言中java 只支持单继承,不支持多继承。因为多继承容易带来安全隐患当多个父类中定义了相同方法时,当功能不同,不确定要运行A还是B但是java保留了这种机制,java用另一种体现机制来完成表示。叫多实现。

2)继承的扩展:子父类关系

子父类中的函数。当子类中出现和父类一模一样的函数时候,当子类对象调用该函数,会运行子类函数的内容。如同父类的函数被覆盖一样。这种情况也是函数的另一个特性:重写(覆盖)。

父类,一般称为基类。子父类出现后,出现新特性:

重载:只看同名参数列表。

重写:子父类方法要一模一样。 

子类重写父类中的方法,但是不继承父类方法中的内容,只执行自己重写方法中的内容子类中用super关键字来调用父类中的变量,方法

4)继承的子父类 Demo:

package study.base.day006;public class Fu{int num = 4;void father(){System.out.println("I'm a father");}void speak(){System.out.println("speak");}Fu(){System.out.println("fu lei de gzhs");}}

子类继承父类:

package study.base.day006;public class Zi extends Fu{int num = 5;Zi(){//super();默认执行了superSystem.out.println("zi lei de gzhs");}void show(){//父类中的num不能私有化System.out.println(super.num);//子类中用super关键字来调用父类中的变量,方法int i = super.num;super.father();}//子类重写父类中的方法,但是不继承父类方法中的内容,只执行自己重写方法中的内容void speak(){//递归方法,调用父类中的show()方法,执行父类show()方法//this.speak();super.speak();System.out.println("aaaa");}}

四、抽象类与抽象方法

1) 概念:在面向对象的概念中,所有的对象都是通过来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。

2) 抽象类:当一个类被声明为abstract时,这个类被称为抽象类。所谓的抽象类就是没有实例对象的类。

3) 抽象方法:作为修饰符,abstract声明了一种没有具体对象的,出于组织概念的层次关系需要而存在的抽象类;作为类方法修饰符,abstract则声明了一种仅有方法头,而没有具体的方法体和操作实现的抽象方法。

4) 个人理解:当父类中的一个方法,无法确定其具体的实现形式,那么就要用到抽象方法。而这些不去实现抽象方法的类就是抽象类。

代码演示:

public abstract class Animal {abstract void eat();<span style="white-space:pre"></span>//提高了代码的复用性public static void func(Animal a){a.eat();}}

五、接口

1) 概念:Java接口是一系列方法的声明,是一些方法特征的集合,一个接口只有方法的特征没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的行为(功能)。

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

3)定义接义时的格式特点:

1、接口中常见定义:常量,抽象方法。

2、接口中的成员都有固定的修饰符。

常量:public static final

方法:public abstract 

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

demo:

public interface InterFace {public static final double PI = 3.14;public abstract void show();}public class InferFaceTest implements InterFace,InterFaceA{@Overridepublic void show() {System.out.println("show");}@Overridepublic void show2() {}}

六、面向对象的多态:

指同一个实体同时具有多种形式就好比养宠物,你家养了猫,别人家养了狗,但是猫和狗都称作为宠物,或者动物。

继承是多态产生的前提条件

多态的特点:

1、提高了代码的复用性

2、多态至始至终都是子类对象在做变化。

<pre name="code" class="html">public class PolymorphismDemo {public static void main(String[] args) {//类型提升。向上转型Animal a = new Cat();a.eat();//func(new Cat());func(new Dog());//强制将父类的引用,转成子类类型。向下转型。//多态至始至终都是子类对象在做变化。Cat c = (Cat)a;c.catchMouse();}public static void func(Animal a){//提高了代码的复用性a.eat();// a  指向Cat 类if(a instanceof Cat){//判断 a 是谁的实例。如果是,就执行。Cat c  = (Cat)a;c.catchMouse();}else if(a instanceof Dog){Dog d = (Dog)a;d.watchHome();}}}多态的练习:/** * 需求: * 电脑运行实例 * 电脑运行基于主板 */package study.base.day007;public class PolymorphismDemo2 {public static void main(String[] args) {MainBoard mb = new MainBoard();mb.run();mb.usePCI(new NetCard());}}interface PCI{public void open();public void close();}class MainBoard{public void run(){System.out.println("main board run");}public void usePCI(PCI pci){if(pci!=null){pci.open();pci.close();}}}class NetCard implements PCI{public void open(){System.out.println("netcard open");}public void close(){System.out.println("netcard close");}}

七、单例设计模式(Singleton):

解决一个类在内存中只存在一个对象。想要保证对象的唯一。

1、为了避免其它程序过多的建立对象,先禁止其他程序建立该类对象。

2、还为了让其他程序可以访问到该类对象,只好在本类中,自定义一个对象。

3、为了方便其它程序对自定义对象的访问,可以对外提供一些访问方式。

这三步的具体实现:

1、将构造方法私有化

private void String getName(String name){

this.name = name;

}

2、在类中创建一个本类对象

Person p = new Person();

3、提供一个方法,可以获取该对象p

单例模式-->

饿汉式与懒汉式

饿汉式:类一进内存,就创建好对象。

private static Single2 s2 = new Single2(); //直接 初始化

private Single2();

public static Single2 getInstance(){return s;}

 

懒汉式对象方法被调用时,才初始化,也叫做对象的延时加载

Single 类进内存,对象还没有存在,只是调用了getInstance方法时,才建立对象。

synchronized给代码块或者方法加锁,保证只有同一时刻只有一个线程执行,但是会降低系统的效率

private static Single2 s2 = null;private static Single2 getInstance(){if(s2==null){//如果多人同时访问,但是cpu没有办法同时处理多个程序,所以就报错了。synchronized(Single2.class){if(s2==null){s2 = new Single2();//重新 初始化 了一个Single2对象}}}return s2;}

八、内部类和匿名内部类

内部类的访问规则:

1)内部类可以直接访问外部类中的成员,包括私有。

之所以可以直接访问外部类中的成员,是因为内部类中持有了一个外部类的引用,

格式为:外部类类名.this.xx

2)外部类要访问内部类,必须建立内部类对象。

访问格式:

1、当内部类定义在外部类的成员位置上,而且非私有,可以在外部其它类中,

可以直接建立内部类对象,

格式:

外部类名.内部类名  变量名 = 外部类对象.内部类对象。

OuterClass.InnerClass ic = new OuterClass().new InnerClass();

3)当内部类在成员位置上,就可以被成员修饰符修饰。

比如,private:将内部类在外部类中进行封装。

static:内部类可以被静态修饰,就具备了静态的特性。

但是当被static修饰符修饰了后,只能直接访问外部类中的static成员。

出现了访问局限。

注意:当内部类中定义了静态成员,该内部类必须是 static 的。

 当外部类中的静态方法访问内部类时,内部类也必须是 static 的。

当描述事物时,事物的内部还有事物,该事物用内部类来描述。

因为内部事务在使用外部事物的内容。

4)匿名内部类:

1、匿名内部类其实就是内部类的简写格式。

2、定义匿名内部类的前提。内部类必须继承一个类或者实现一个接口。

package study.base.day007;public class OuterClass {private static final int x = 4;public static void main(String[] args) {}class InnerClass{ void show(){//System.out.println("inner:"+OuterClass.this.x);//同下 System.out.println("inner:"+x);}}void viewInner(){InnerClass ic = new InnerClass();ic.show();}}class InnerClassDemo2{public static void main(String[] args) {OuterClass.InnerClass ic = new OuterClass().new InnerClass();ic.show();}}

九、枚举

枚举的描述:

1枚举就相当于一个类,其中也可以定义构造方法、成员变量、普通方法和抽象方法。

   子类完成父类的抽象方法。子类的构造方法就是调用父类的无参数构造方法,也可

   以指定传入参数的构造方法。枚举通常用于内部类的使用。

2) 枚举元素必须位于枚举体中的最开始部分,枚举元素列表的后要有分号与其他成员分隔。

      把枚举中的成员方法或变量等放在枚举元素的前面,编译器报告错误。所以枚举的构造

      方法一定要放在变量后面。

3) 带构造方法的枚举

      构造方法必须定义成私有的。

      如果有多个构造方法,该如何选择哪个构造方法?

      枚举元素如MON和MON()的效果一样,因为都是调用默认的构造方法。

4) 带方法的枚举

      定义枚举TrafficLamp;

      实现普通的next方法;

      实现抽象的next方法:每个元素分别是由枚举类的子类来生成的实例对象,

      这些子类采用类似内部类的方式进行定义;

      增加上表示时间的构造方法.

5) 枚举只有一个成员时,就可以作为一种单例的实现方式。

6) Demo 

package study.part3.day018.enumstudy;public abstract class WeekDay {//私有化构造函数private WeekDay(){}public final static WeekDay SUN = new WeekDay(){@Overridepublic WeekDay nextDay() {return MON;}};public final static WeekDay MON = new WeekDay(){@Overridepublic WeekDay nextDay() {return SUN;}};//定义一个抽象方法,nextDaypublic abstract WeekDay nextDay();}package study.part3.day018.enumstudy;public class EnumTest{public static void main(String[] args) {System.out.println(WeekDay.SUN);}public enum WeekDay{SUN,MUN,THU,WEN,THR,FIA,SAT;WeekDay(){}}public enum TrafficLamp{//添加了构造方法后,这里就得加上一个小括号,把 int 类型的time参数传进去//这样就表示了它是调用了具体的哪一个构造方法,它是谁的子类RED(30) {@Overridepublic TrafficLamp nextLamp() {return GREEN;}},GREEN(13) {@Overridepublic TrafficLamp nextLamp() {return YELLOW;}},YELLOW(20) {@Overridepublic TrafficLamp nextLamp() {return RED;}};//定义一个抽象的下一次显示的灯public abstract TrafficLamp nextLamp();private int time;//构造方法TrafficLamp(int tim){this.time = tim;}}}

十、基本数据类型对象包装类

 * 基本数据类型对象包装类

 * 基本数据类型 引用数据类型

 * byte Byte

 * short Short

 * int Integer

 * long Long

 * boolean Boolean

 * float Float

 * double Double

 * char Character

 * 基本数据类型对象包装类的最常见作用。

 * 就是用于基本数据类型和字符串类型之间做转换

 * 基本数据类型转成字符串。

 * 1--基本数据类型+""

 * 2--基本数据类型.toString(基本数据类型值);

 * 如:Integer.toString(34);//将整数34转成字符串"34"

 * 字符串转成基本数据类型。

 * 基本数据类型

 * xxx a = Xxx.parseXxx(String);

 * int a = Integer.parseInt(str);

 * double b = Double.parseDouble("12.33");

 * boolean b = Boolean.parseBoolean("true");

 * Integer i = new Integer("2123");

 * int num = i.intValue();

 * 十进制转成其它进制:

 * toBinaryString()

 * toHexString()

 * toOctalStirng();

 * 其它进制转十进制:

 * parseInt()

package study.base.day010.ThreadTX;public class BaseDateObject {public static void main(String[] args) {//整数类型的最大值sc("int max:"+Integer.MAX_VALUE);sc("int min:"+Integer.MIN_VALUE);int num = Integer.parseInt("123215");System.out.println(num);long l = Long.parseLong("34");System.out.println(Integer.toBinaryString(6));System.out.println(Integer.toHexString(67));/** * 其它进制转十进制 */int i = Integer.parseInt("3c",16);System.out.println("3c转成十进制是:"+i);}public static void sc(String str){System.out.println(str);}}

十一、递归与迭代:

/** * 递归与迭代 */package study.base.day006;public class DiGui {public static void main(String[] args) {int i = fib(5);System.out.println(1);}static int fib(int n)  {     if(0 == n)         return 0;     if(1 == n)         return 1;     if(n > 1)         return fib(n-1)+fib(n-2);   else   return n;}//递归Demo  int funcA(int n)  {      if(n > 1)         return n+funcA(n-1);      else          return 1;  }  //迭代Demoint funcB(int n)  {      int i,s=0;      for(i=1;i<n;i++)       s+=i;      return s;}}


0 0
原创粉丝点击