黑马程序员之java面向对象概念学习

------- android培训java培训、期待与您交流! ----------

面向对象:

面向对象是相对面向过程而言的;

面向过程强调的是功能行为,面向对象是将功能封装进对象,强调具备了功能的对象,面向对象是基于面向过程的.

面向对象三个特征:

封装(Encapsulation):指隐藏对象的属性和实现细节,及对外提供公共访问方式(public修饰的类成员),

好处:将变化隔离(可以扩展,不会影响已存在的程序),便于使用,提高重用性,提高安全性;

原则:将不需要对外提供的内容都隐藏起来;把属性都隐藏,提供公共方法对其访问,之所以提供访问方式因为可以在

访问方式中加入逻辑判断等语句,对访问的数据进行操作,提高了代码健壮性;

体现形式:权限的设置private,public,默认

继承(extends):必须是类与类之间有所属关系才可以继承

作用:1,提高了代码的复用性;

2,让类与类之间产生了关系,有了这个关系才有了多态的特性,Java语言中只支持单继承,不支持多继承,因为多继承容易带来安全隐患,当多个父类中定义了相同功能,当内容不同时不能确定要执行那个功能;但是Java保留这种机制,可以实现多个接口;

Java支持多层继承,也就是一个继承体系;如何使用一个继承体系,简单一句话:查阅父类功能,创建子类对象使用功能;

1,变量:如果子类中出现非私有的同名成员变量时,子类访问本类中的变量用this.变量名,子类要访问父类中同名变量使用super.变量名;

2,函数:当子类出现和父类一模一样的函数时,当子类对象调用该函数时,会运行子类自己定义的函数,如同父类的函数被覆盖了一样,即重写;

3,构造函数:子类所有的构造函数第一行默认有一句隐式super(),当创建子类对象时,父类的构造函数(无参的那个)也会被执行;子类一定要访问父类中构造函数,因为父类中的数据子类可以直接获取,所以子类对象在建立时,需要先查看父类是如何对这些数据进行初始化的,所以子类在对象初始化时,要先访问一下父类的构造函数,如果要访问父类中指定的构造函数,可以通过手动定义super语句的方式指定;当然,子类的构造函数第一行也可以手动指定this语句来访问本类中的构造函数,但是,子类中至少有一个构造函数会访问父类的构造函数;

覆盖(重写):父类中的成员不能是private权限,因为子类看不见父类的private成员;

1,子类覆盖父类,必须保证子类权限大于等于父类权限,才可以覆盖否则编译失败;

2,静态只能覆盖静态;

final(关键字):一个修饰符,可以修饰类,函数,变量;

1,被final修饰的类不能被继承,为了避免被继承后功能被子类重写;

2,被final修饰的方法不能被重写;

3,被final修饰的变量是一个常亮只能被赋值一次,既可以修饰成员变量,也可以修饰局部变量;

4,内部类定义在类中的局部位置上时,只能访问该局部被final修饰的局部变量;

abstract(抽象):一个修饰符,可以修饰类,函数;作用,不让类创建对象,抽象类中可以不定义抽象方法;

1,抽象方法一定在抽象类中;

2,抽象方法和抽象类都必须被abstract关键字修饰;

3,抽象类不可以用new创建对象,因为调用抽象方法没意义;

4,抽象类中的抽象方法要被使用,必须由子类复写所有的抽象方法,创建子类对象调用;

如果子类只覆盖了部分抽象方法,那么该子类还是一个抽象类;

interface(接口):用于定义接口,接口用于功能扩展的,格式 interface 接口名{}      

接口中常见定义:常量,抽象方法;

接口中成员都有固定修饰符:常量:public static final;方法:public abstract;

接口中的成员都是public的,上面的固定修饰符都可以省略,编译器默认加上;

接口不可以创建对象,因为有抽象方法;需要被子类实现(implements),子类对接口中抽象方法全都覆盖后,子类才可以实例化,否则子类是一个抽象类;

接口可以被类多实现,也是对多继承不支持的转换:class C implements A,B{}

接口之间也存在继承关系:interfaceA extends B,C{}//接口的继承支持多继承,保证BC中不存在同名不同返回值的方法;

类之间的关系除了继承还有聚合,组合:

聚合:事物A由事物B等组成,但是事物A缺失了组成元素中某一个事物B不会影响事物A的自身属性和功能;

组合:事物A由事物B等组成,但是一旦事物A缺失了组成元素 

多态:

1,多态的体现:父类的应用指向了自己的子类对象,父类的应用也可以接收自己的子类对象;

2,多态的前提:必须是类与类之间有关系,要么继承,要么实现;通常还有一个前提,存在覆盖;

3,多态的好处:多态出现大大提高了程序的扩展性;

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

4,多态的应用:接口降低了程序的耦合性,使多态扩展性提高

5,多态成员函数使用特点:

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

在多态中成员变量:无论在编译时,还是运行时都参阅左边(引用型变量所属的类);

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

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

            Cat c = (Cat)a;//强制将父类的应用,转成子类类型,向下转型

            Animal a = newAnimal();

            Cat c = (Cat)a;//这种转换是错误的,因为不能将父类对象转成子类类型

注:父类应用指向了自己子类的对象时,该应用可以被提升,也可以被强制转换,多态自始至终都是子类对象在做变化。

类和对象的关系:

类是对现实生活中事物的描述,映射到java中,描述就是class定义的类;

对象是这类事物,实实存在的个体,具体的对象就是对应java在堆内存中创建的对象;

匿名对象:是对象的简化形式,有两种使用情况,当对象方法仅进行一次调用时,匿名对象可以作为实际参数进行传递;  

构造函数:函数名和类名相同,不用定义返回值类型,不可以写return语句;

作用:给对象初始化,建立就会调用与之对应的构造函数;

当一个类中没有定义构造函数时,那么系统会默认给该类加入一个空参数的构造函数;

构建函数只在创建对象时调用一次;

构造代码块:给对象进行初始化,定义的是不同对象共性问题,对象一建立就执行,而且优先于构造函数执行

静态代码块:static{执行语句},随着类的加载而执行,只执行一次,用于给类进行初始化

public classStaticDemo{

public staticvoid main(String[] args){

 newStaticCode();

newStaticCode();

}//执行结果:aStaticCode StaticCode

}

class StaticCode{

static{

System.out.print('a'+"");

}//只有用到类里面的内容是才会执行静态代码块

publicStaticCode(){

System.out.print("StaticCode");

}

}

和构造函数区别:构造代码块是给所有的对象进行一次初始化,而构造函数时给对应的对象初始化

this:就代表本类的对象,this代表它所在函数所属对象的引用;简单说,哪个对象调用this所在的函数,this就代表哪个对象;

当定义类中功能时,该函数内部要用到调用该函数的对象时,这时用this来表示这个对象;

this():语句用于构造函数间调用,但是对 this 的调用必须是构造函数中的第一个语句;

static:静态关键字;用于修饰成员(成员变量和成员函数),被修饰的成员放在共享区(方法去/数据区)

被修饰后的成员具备的特点:随着类的加载而加载,静态会随着类的消失而消失,非静态成员随着对象的消失而消失;

优先于对象存在;被所有的对象所共享;可以直接被类名调用,类名.成员;

static Stringcountry="CN";//这个country成员变量无论你创建多少个对象,在内存中都只有一个

用法:是一个修饰符,用于修饰成员只能修饰成员,被static修饰的成员在内存中只被分配一次空间,这个空间可以被多个对象实例使用;

实例变量(非static)和类变量(static)的区别:    

1,存放位置:类变量存放在方法区中,实例变量随着对象的创建而存在于堆内存中;

2,生命周期:类变量生命周期最长,随着类的消失而消失,实例变量生命周期随着对象的消失而消失;

静态的使用注意事项:

1,静态方法只能访问静态成员,非静态方法既可以访问静态也可访问非静态;

class Person{

privateString name;

privateint age;

publicstatic void show(){

System.out.println(name);//报错:无法从静态上下文中引用非静态 变量 name

}

}

2,静态方法中不可以定义this,super关键字,因为静态优先于对象存在,所以静态方法中不可以出现this,也就是说静态方法调用this还没有对应的对象存在呢;

3,主函数是静态的,是一个特殊的函数,作为程序的入口,可以被jvm调用,主函数是固定格式的为了jvm识别;

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

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

2,执行类中的static代码块,如果有的话,给Person.class类进行初始化;

3,在堆内存中开辟空间,分配内存地址;

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

5,对属性进行显示初始化;

6,对对象进行构造代码块初始化;

7,对对象进行对应的构造函数初始化;

8,将内存地址付给栈内存中的p变量;

设计模式:解决某一类问题最行之有效的方法

java中有23中设计模式:

单例设计模式:解决一个类在内存中只有一个对象存在;定义单例模式一般使用饿汉式;

想要保证对象唯一:

1,为了避免其他程序过多创建该类对象,先禁止其他程序创建该类对象;

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

3,为了方便其他程序对自定义的对象的访问,可以对外提供一些访问方法;

classSingle{//饿汉式:Single类一进内存,就已经创建了对象

privateSingle(){};//1

Singles = new Single();//2

publicstatic Single getInstance(){//3

returns;

}

}       

classSingle{//懒汉式:Single类进内存,对象还没有存在,只有调用了getInstance方法时才创建对象;

privateSingle(){};//1

Singles = null;

publicstatic synchronized Single getInstance(){//3;synchronized锁保证唯一性但是降低了运行效率

if(s== null)//进入if后执行new前可能被CPU暂停执行下一个程序(这个程序创建了Single对象),再回来继续执行new这个时候堆中就有两个Single对象了

s= new Single();//2

returns;

}

}       

模板方法设计模式:在定义功能室,功能的一部分是确定的,但是有一部分是不确定的,而确定的部分在使用不确定的部分,那么这时候就将不确定的部分暴露出去,由该类的子类去完成

例子:abstractclass GetTime{

publicvoid getTime(){

longstart = System.currentTimeMillis();

runcode();

longend = System.currentTimeMillis();

System.out.println(end-start);

}

publicabstract void runcode();//由于具体要运行代码不确定,这个不确定也可以由默认的实现,根据开发需求而定

}                

练习1:this的作用练习
class Person{
         private String name;
         private int age;
         Person(int age){
                   this.age = age;
         }
         Person(String name,int age){
                   this(age);
                   this.name = name;
                   //this.age = age;
         }
         public boolean compareAge(Personp){
                   return this.age ==p.age;
         }
}
class PersonDemo1{
         public static void main(String[]args){
                   Person p1 = newPerson(23);
                   Person p2 = newPerson(34);
                   System.out.println(p1.compareAge(p2));
         }
}
练习2:抽象类练习
/*
假如我们在开发一个系统是需要对员工进行建模,员工包含3个属性,姓名、工号、以及工资,除了
含有员工属性外,另外还有一个奖金属性,请使用继承的思想设计出员工类和经理类,要求类中提供必要
的方法进行属性访问
*/
abstract class Employee{
         private String name;
         private String id;
         private double pay;
         Employee(String name,Stringid,double pay){
                   this.name = name;
                   this.id = id;
                   this.pay = pay;
         }
         public abstract void work();
}
class Pro extends Employee{
         Pro(String name,String id,doublepay){
                   super(name,id,pay);
         }
         public void work(){
                   System.out.println("Prowork");
         }
}
class Manager extends Employee{
         private int bonus;
         Manager(String name,Stringid,double pay,int bonus){
                   super(name,id,pay);
                   this.bonus = bonus;
         }
         public void work(){
                   System.out.println("Managerwork");
         }
}

------- android培训java培训、期待与您交流! ----------

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值