------- android培训、java培训、期待与您交流! ----------
面向对象:封装
Private:权限修饰符,用于修饰类中的成员(成员变量,成员函数)
私有成员只在本类中有效,向外部提供一种访问方式,举例:
class Person
{
private int age;
public void setAge(int age)
{
if(age>0&&age<150)
{
this.age=age;
System.out.println("age="+age);
}
else
{
System.out.println("Fault age");
}
}
public int getAge()
{
return age;
}
}
class PersonDemo
{
public static void main(String[] args)
{
Person p =new Person();
p.setAge(20);
p.setAge(-20);
}
}
当一个类中没有定义构造函数时,系统会默认给该类加入一个空参数的构造函数。
在类中自定义了构造函数后,默认的构造函数(空参数构造函数)就没有了。
构造函数是在对象一建立就运行,给对象初始化。一个对象建立,构造函数只运行一次。
构造代码块:
class Person
{
{//构造代码块
System.out.println("cry");
}
private int age;
}
对象一建立就运行,构造代码块是给所有对象初始化(定义不同对象共性内容),而构造函数是给对应对象初始化。
This的用法
1.代表他所在函数所属对象的引用;(哪个对象在调用this所在的函数,this就代表哪个对象)
this.n=n;
this的应用:当定义类中功能时,该函数内部要用到调用该函数的对象时,用this表示这个对象。
举例:
public class CompareAge
{
public static void main(String[] args)
{
Person p1=new Person(20);
Person p2=new Person(25);
boolean b=p1.compare(p2);
System.out.println(b);
}
}
class Person
{
int age;
Person(int age)
{
this.age=age;
}
public boolean compare(Person p)
{
return this.age==p.age;
}
}
2.this语句:用于构造函数之间相互调用;(this语句只能放在构造函数的第一行,因为初始化动作要先执行)
Person(Stringname)
{
this.name=name;
}
Person(Stringname, int age)
{
this(name);
this.age=age;
}
static修饰符
是一个修饰符,用于修饰成员变量和成员函数;
当成员被静态修饰后,就多了一个调用方式,除了可以被对象调用外,还可以直接被类名调用:类名.静态成员。(不用创建对象)
静态使用注意事项:
1. 静态方法只能访问静态成员;
非静态方法既可以访问静态成员,也可以访问非静态成员
2. 静态方法中不可以出现this,super关键字
因为静态优先于对象存在,所以静态方法中不能出现this关键字
什么时候使用静态方法?
当功能内部没有访问到非静态数据(对象的特有数据)时,可以定义成静态方法。
静态代码块:随着类的加载而执行,只执行一次,并优先于主函数执行
classStaticCode
{
static
{
System.out.println(“hiahiahia”);
}
}
单例设计模式
class Student//只能创建该类的一个对象
{
private Student(){}
private static Student s=new Student();
public static Student getInstance()
{
return s;
}
}
classStudentDemo
{
public static void main(String [] args)
{
Students=Student.getInstance();
}
}
饱汉模式:
class Student//只能创建该类的一个对象
{
private Student(){}
private static Student s=new Student();
public static Student getInstance()
{
return s;
}
}
饥汉模式:
class Student//只能创建该类的一个对象
{
private Student(){}
private static Student s=null;
public static Student getInstance()
{
if(s==null)
s= new Student();
return s;
}
}
继承:
1. 提高了代码的复用性;
2. 让类与类之间产生了关系,有了这个关系,才有了多态的特性。
Java语言只支持单继承,不支持多继承,因为多继承容易带来安全隐患。但在接口中支持多继承(多实现,因为接口中没有具体的方法)
类之间的聚合关系:
class C extendsA,B
如果子类中出现非私有的同名成员变量时,子类要访问本类中的成员变量,用this. ;子类要访问父类中的成员变量,用super.。
子类继承父类之后,可以在子类中通过重写函数内容覆盖父类中的方法。子类覆盖父类,必须保证子类函数的权限大于等于父类函数的权限,否则编译失败。
重载:只看同名函数的参数列表;(参数个数不一样,个数不同时,参数类型也可不一样)
重写:子父类方法必须一模一样。
为什么子类一定要访问父类中的构造函数
因为父类中的数据子类可以直接获取,所以子类对象在建立时,需要先查看父类是如何对这些数据进行初始化的。所以子类在对象初始化时,要先访问一下父类中的构造函数。如果要访问父类中指定的构造函数,可以通过手动定义super语句的方式来指定。
子类的所有构造函数默认都会访问父类中空参数的构造函数,当父类中没有空参数的构造函数时,子类必须手动通过super语句的形式来指定要访问父类中的构造函数。当然,子类的构造函数第一行也可以手动指定this语句来访问本类中的构造函数。子类中至少会有一个构造函数会访问父类中的构造函数。
举例:
class Fu
{
int num;
Fu(int n)
{
System.out.println(“fu….”+n);
}
}
class Ziextends Fu
{
Zi()
{
super(4);
System.out.println(“zi run”);
}
}
class StudentDemo
{
public static void main(String[] args)
{
new Zi();
}
}
final修饰符
可以修饰类,函数,变量;
被final修饰的类不能被继承,为了避免被继承,被子类复写功能,使用final修饰。
被final修饰的方法不允许被复写。
被final修饰的变量变为常量。
抽象类
抽象类比一般类多了个抽象函数,就是在类中建立抽象方法,抽象类不可以实例化。
抽象类可以不定义抽象方法,这样做仅仅是不让该类建立对象。
抽象类中的抽象方法要被使用,必须由子类复写所有的抽象方法后,建立子类对象调用,如果子类只覆盖了部分抽象方法,那么该子类还是一个抽象类。
举例(模板方法),求一段代码的运行时间,使用抽象类:
abstract class GetTime
{
public final void getTime()
{
long start=System.currentTimeMillis();
runcode();
long end=System.currentTimeMillis();
System.out.println("Run time="+(end-start));
}
public abstract void runcode();
}
class SubTimeextends GetTime
{
public void runcode()
{
for(int i=0;i<1000;i++)
System.out.print(i);
}
}
public class ProgRuntime
{
public static void main(String[] args)
{
SubTime t1=new SubTime();
t1.getTime();
}
}
接口:
初期理解:接口中定义的方法都是抽象方法;
接口定义时,格式特点:
1.接口中常见定义:常量,抽象方法;
2.接口中的成员都有固定修饰符:
常量:public staticfinal
方法:public abstract
接口是不能创建对象的,因为有抽象方法。
需要被子类实现,子类在覆盖接口中所有的抽象方法后,才可以实例化。
接口可以被类多实现,也是对多继承不支持的转换形式。
interface Inter
{
public staticfinal double PI=3.14;
public abstractvoid show();
}
interface InterA
{
public abstract void show();
}
class demo
{
public void func()
{
System.out.println("haha");
}
}
class Test extends demo implements Inter,InterA{
public void show(){}
}
面向对象的特征
计算机软件系统是现实生活中的业务在计算机中的映射,而现实生活中的业务其实就是一个个对象协作的过程。面向对象编程就是按现实业务一样的方式将程序代码按一个个对象进行组织和编写,让计算机系统能够识别和理解用对象方式组织和编写的程序代码,这样就可以把现实生活中的业务对象映射到计算机系统中。
面向对象的编程语言有封装、继承 、抽象、多态等4个主要的特征。
1封装:
封装是保证软件部件具有优良的模块性的基础,封装的目标就是要实现软件部件的“高内聚、低耦合”,防止程序相互依赖性而带来的变动影响。在面向对象的编程语言中,对象是封装的最基本单位,面向对象的封装比传统语言的封装更为清晰、更为有力。面向对象的封装就是把描述一个对象的属性和行为的代码封装在一个“模块”中,也就是一个类中,属性用变量定义,行为用方法进行定义,方法可以直接访问同一个对象中的属性。通常情况下,只要记住让变量和访问这个变量的方法放在一起,将一个类中的成员变量全部定义成私有的,只有这个类自己的方法才可以访问到这些成员变量,这就基本上实现对象的封装,就很容易找出要分配到这个类上的方法了,就基本上算是会面向对象的编程了。把握一个原则:把对同一事物进行操作的方法和相关的方法放在同一个类中,把方法和它操作的数据放在同一个类中。
例如,人要在黑板上画圆,这一共涉及三个对象:人、黑板、圆,画圆的方法要分配给哪个对象呢?由于画圆需要使用到圆心和半径,圆心和半径显然是圆的属性,如果将它们在类中定义成了私有的成员变量,那么,画圆的方法必须分配给圆,它才能访问到圆心和半径这两个属性,人以后只是调用圆的画圆方法、表示给圆发个消息而已,画圆这个方法不应该分配在人这个对象上,这就是面向对象的封装性,即将对象封装成一个高度自治和相对封闭的个体,对象状态(属性)由这个对象自己的行为(方法)来读取和改变。一个更便于理解的例子就是,司机将火车刹住了,刹车的动作是分配给司机,还是分配给火车,显然,应该分配给火车,因为司机自身是不可能有那么大的力气将一个火车给停下来的,只有火车自己才能完成这一动作,火车需要调用内部的离合器和刹车片等多个器件协作才能完成刹车这个动作,司机刹车的过程只是给火车发了一个消息,通知火车要执行刹车动作而已。
抽象:
抽象就是找出一些事物的相似和共性之处,然后将这些事物归为一个类,这个类只考虑这些事物的相似和共性之处,并且会忽略与当前主题和目标无关的那些方面,将注意力集中在与当前目标有关的方面。例如,看到一只蚂蚁和大象,你能够想象出它们的相同之处,那就是抽象。抽象包括行为抽象和状态抽象两个方面。例如,定义一个Person类,如下:
class Person
{
Stringname;
int age;
}
人本来是很复杂的事物,有很多方面,但因为当前系统只需要了解人的姓名和年龄,所以上面定义的类中只包含姓名和年龄这两个属性,这就是一种抽像,使用抽象可以避免考虑一些与目标无关的细节。我对抽象的理解就是不要用显微镜去看一个事物的所有方面,这样涉及的内容就太多了,而是要善于划分问题的边界,当前系统需要什么,就只考虑什么。
继承:
在定义和实现一个类的时候,可以在一个已经存在的类的基础之上来进行,把这个已经存在的类所定义的内容作为自己的内容,并可以加入若干新的内容,或修改原来的方法使之更适合特殊的需要,这就是继承。继承是子类自动共享父类数据和方法的机制,这是类之间的一种关系,提高了软件的可重用性和可扩展性。
多态:
多态是指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并不确定,而是在程序运行期间才确定,即一个引用变量倒底会指向哪个类的实例对象,该引用变量发出的方法调用到底是哪个类中实现的方法,必须在程序运行期间才能决定。因为在程序运行时才确定具体的类,这样,不用修改源程序代码,就可以让引用变量绑定到各种不同的类实现上,从而导致该引用调用的具体方法随之改变,即不修改程序代码就可以改变程序运行时所绑定的具体代码,让程序可以选择多个运行状态,这就是多态性。多态性增强了软件的灵活性和扩展性。例如,下面代码中的UserDao是一个接口,它定义引用变量userDao指向的实例对象由daofactory.getDao()在执行的时候返回,有时候指向的是UserJdbcDao这个实现,有时候指向的是UserHibernateDao这个实现,这样,不用修改源代码,就可以改变userDao指向的具体类实现,从而导致userDao.insertUser()方法调用的具体代码也随之改变,即有时候调用的是UserJdbcDao的insertUser方法,有时候调用的是UserHibernateDao的insertUser方法:
UserDao userDao = daofactory.getDao();
userDao.insertUser(user);