Java面向对象之初步了解
基本概念:
1.1 面向对象时相对面向过程而言的,他们都是一种思想;
1.2 面向过程:强调的是功能行为;
1.3 面向对象:试讲功能封装进对象,强调具备功能的对象。
1.4 面向对象是基于面向过程的。
2.1 面向对象的特点:
像采取了人们现实生活的模式一样,把复杂的事情简单化
把程序员从执行者转化成了指挥者。
例如:完成需求时,先要找具有所需功能的对象来用是吧?那如果对象不在,那我们就自己造一个。这样就简化了开发并提高了复用。
那实际上我们在开发时:就是不断的创建新的对象,然后把零零总总的逐个执行的对象的动作全部封装起来,指挥他做我们需要他做的事。而在设计时:就是在管理和维护每个对象之间的关系!
类与对象的关系:
Java中描述事物是通过类的形式来体现
类:是具体事务的抽象,概念上的定义。
对象:是该类事物实实在在存在的个体。
他们之间的关系如下图关系
对于类的定义:
比如在生活中我们描述一个人有年龄身高等自己的属性,同时还有吃饭说话走路等行为,所以java中对于类也是这样:
属性:对应类中的成员变量;
行为:对于类中的成员函数;
总的来说,定义类就是在定义类中的成员(成员变量和成员函数);
成员变量和局部变量的区别?
成员变量:
1, 在定义的类中整个类都可以访问他;
2, 他是随着对象的建立而建立的,存在对象坐在的堆内存中。
3, 他有默认的初始化值;
局部变量;
1, 局部顾名思义,只能调用者局部范围,比如函数内,语句内等;
2, 局部变量存在栈内存中;
3, 当他作用范围结束了,空间会自动释放;
4, 他没有默认初始化值。
知识点:匿名对象
匿名对象时对象的简化形式
他有两种使用情况:
1, 当对象的方法仅调用一次时使用;
如://Car c = new Car();
//c.num = 5;
new Car().num = 5;
new Car().color = “blue”;
2, 他可以作为实际参数进行传递;
如:之前定义了一个show()方法
Show(new Car());
OOP的三大特征:
封装(encapsulation)
继承(inheritance)
多态(polymorphism)
三大特征之封装(encapsulation)
6.1.1 他就是把对象的属性和实现细节给隐藏起来,对外只提供公告的访问方式。
6.1.2 他的好处(如电脑主机):
1,首先就是很安全有一个外壳;
2,把容易受影响和变化的部件有效隔离;
3, 访问方式很方便
4, 提高了复用性;
6.1.3 他的原则:
1,把不需要对外提供的内容都隐藏起来;
2,把属性都隐藏,提高公共的访问方式
Private(私有)关键字
6.2.1 private关键字:
1,是一个权限休息符;
2,用于修饰成员(成员变量和成员函数);
如:private int name = 2;
private void show(){}
3,被私有化的成员只能在本类中有效;
6.2.2 常用方法:
将成员变量私有化后,有一些仍需对外提供访问,我们定义set,get方法,这样就提高了对数据的安全。
构造函数
7.1.1 特点:
1,函数名与类名相同;
2,不要定义返回值类型;
3,不可以写return 语句;
如:
class Demo{
int name = 2;
Demo(int name){
This.name = name;
}
}
小细节:
1,函数一建立就会调用与之对应的构造函数;
2,他的作用是给对象进行初始化。
3,当一个类中没有定义构造函数,系统会默认的给加一个空参数构造函数,你有 定义,那么默认的就没有了。
4,多个构造函数是以重载的形式存在的。
区别:
构造函数和一般函数在写法上有不同,在运行上也不同。
构造函数已建立就运行初始化对象,而方法是对象调用才执行是给对象添加功能。
另外,构造函数只运行一次,而一般函数可以多次调用。
什么时候定义构造函数?
当分析事物存在一些特性或者行为,那么将这些内容定义在构造函数中。
构造代码块
作用:给对象进行初始化。
对象已建立就运行,而且优先于构造函数执行。
和构造函数的区别:
构造代码块是给所有的对象统一进行初始化,
而构造函数是给对应的对象初始化。
注意:这个小细节经常用于面试,主要看执行顺序,另外构造代码块中定义的是不同对象共性的初始化内容,比如:才出生孩子都会Cry();
this关键字
9.1.1 特点:
this代码其所在函数所属对象的引用。简单理解,this代表本类对象的引用。
9.1.2什么时候使用this关键字?
当函数内需要用到调用该函数的对象时,就用this
This语句,用于构造函数之间进行互相调用,表示:this()他只能定义在构造函数的第一行,因为初始化要先执行。
例如下面这个类:
class Person{
private String name;//私有化成员变量
private int age; {
System.out.println("code run");//构造代码块
}
Person()//构造函数{
//this("hah");
System.out.println("person run");
}
Person(String name){
//this();
this.name =name;
}
Person(String name,int age){
//this(name);
//this.name = name;
this.age = age;
}
}
class PersonDemo4{
public static void main(String[] args) {
new Person();
//Person p = new Person("lisi",30);
//Person p1 = new Person("lisi2",36);
}
}
static(静态)关键字
作用:
用于修饰成员(成员变量和成员函数)
被修饰后的成员具备以下特点;
1, 随着类的加载而加载;
2, 优先于对象存在;
3, 被所有对象所共享;
4, 可以直接被类名调用。
使用注意:
1, 静态方法只能访问静态成员;
2, 静态方法中不可以写this,super等关键字;
3, 主函数是静态的。
实例变量和类变量的区别?
1, 存放位置:类变量随着类的加载而在方法区中;
实例变量随着对象的建立而存在于堆内存中;
2, 生命周期:类变量随着类的消失而消失;
实例变量随着对象的消失而消失;
关于静态的使用问题:
因为静态修饰内容有成员变量和函数,所以要从两方面入手。
1,什么时候定义静态变量?
当对象中出现共享数据时,该数据被静态所修饰。那对于特有的数据就不能定义在这里面了;
2,什么时候定义静态函数?
当功能内部没有访问非静态的数据,那么该功能可以定义静态。
关于static(静态)的应用,工具篇
如:1,定义工具类,class Tool
2, 因为建立对象没有什么意义,所以把构造函数私有化,private Tool(){}
3, 对外提供静态方法方法;
public static void show(){}
4, 在主函数调用方法
Tool.Show();
认识主函数
主函数“public static void main(String[] args)”;
主函数是一个特殊的函数,作为程序的入口,可以被JVM所调用。
主函数定义:
Public:代表函数的访问权限是最大的;
Static: 代表主函数随着类的加载就已经存在了;
Void: 主函数没有具体返回值;
Main: 不是关键字 但是是一个特殊的单词,可以被JVM所识别;
(String[] args): 函数的参数,参数类型是一个数组,该数组中的元素是字符串,字符串类型是数组
主函数是固定格式: 他被JVM识别。
静态代码快
格式:
static{
静态代码块中的执行语句。
}
特点:
随着类的加载而执行,只执行一次,并优先于主函数,是给类初始化的。
例子:求代码执行顺序。面试考点
lass StaticCode{
int num = 9;
StaticCode()//构造函数,给对应对象初始化的{
System.out.println("b");没有调用不执行
}
static{
System.out.println("a");//静态代码块,给类初始化的
}
<span style="white-space:pre"> </span>{
System.out.println("c"+this.num);//构造代码块,给所有对象同一初始化的
}
StaticCode(int x){//带参数的构造函数
System.out.println("d");
}
public static void show()//没有调用,不执行{
System.out.println("show run");
}
}
class StaticCodeDemo {
public static void main(String[] args) {
new StaticCode(4);
<span style="white-space:pre"> </span>}
}打印结果: abc
对象的初始化过程
//Person p = new Person(“lisi”,20);这句话都做了什么事情?
1, 因为new用到了Person.class,所以会先找到Person.class文件并加载到内存中
2, 执行该类中的static 代码块,如果有的话,给Person.class类进行初始化。
3, 在对内存中开辟空间,分配内存地址。
4, 在堆内存中建立对象的特有属性,并进行默认初始化。
5, 对属性进行显示初始化。
6, 对对象进行构造代码块初始化。
7, 对对象进行对应的构造函数初始化。
8, 将内存地址赋给栈内存中的P变量。
单例设计模式
设计模式:解决某一类问题最行之有效的方法。
Java中23中设计模式;
单例设计模式:解决一个类在内存只存在一个对象。
原理步骤:
1, 将构造函数私有化。 目的:禁止其他程序建立该类对像。
2, 在类中创建一个本类对象。 目的:为了让其程序可以访问该类对象。
3, 提供一个方法可以获取该对象。 目的:方便其他程序对自定义对象的访问。
单例设计模式又分饿汉式和懒汉式
饿汉式例子:
分析:先初始化对象,single类一进内存就创建好了对象。
<span style="font-size:18px;">class Single{
private Single(){}
private static Single s = new Single();
public static Single getInstance(){
return s;
}
}</span>
懒汉式例子:
分析:对象时方法被调用时才初始化,也叫对象的延时加载,single类进内存对象没有存在,只有调用了方法才能建立对象。
class Single{
private static Single s = null;
private Single(){}
public static Single getInstance(){
if(s==null){
synchronized(Single.class){
if(s==null)
s = new Single();
}
}
return s;
}
}
//一般开发建议使用饿汉式。
三大特征之继承
概述:
1,当多个类都有相同的属性和行为,我们可以将这些共性的内容单独抽取到一个类里面,其他类只需要继承这个类就可以了;
2,那多个类可以称为子类,抽取出来的单独的类称为父类或超类;
3,子类可以直接访问父类中非私有的属性和行为;
1, 通过关键字extends 让类与类之间产生继承关系。
Class Zi extends Fu{}
好处:
1, 他的出现提高了代码的复用性;
2, 也让类与类之间产生了关系,提供了多态的前提。
特点:
1, java只支持单继承,不支持多继承
class zi extends fu{}//ok
class zi extends fu1,fu2…//error
2, java支持多层继承(继承体系)
class a{}
class b extends a{}
class c extends a{}
3, 继承注意:不要为了获取某类中的某功能区继承,类鱼类之间所属关系是“is a”
Super关键字
1, super和this用法相同;
2, this代表本类应用;
3, super代表父类引用;
4, 当子父类出现同名成员时,可以用super进行区分;
5, 子类要调用父类构造函数时,可以使用super语句。
函数覆盖(Override)
1, 子类中出现于父类一模一样的方法时,会出现覆盖操作称为重写或者复写;
2, 父类私有方法不可以被覆盖;
3, 在子父类覆盖方法中,继续使用被覆盖的方法可以通过super.函数名获取;
4, 覆盖注意事项:子类方法权限要大于父类,静态只能覆盖静态;
什么时候覆盖?
当子类需要父类的功能,而子类有自己特有的内容时,可以复写父类方法,这样沿袭了父类方法又保留自己的特有内容
注意:
重载:只看同名函数参数列表;
重写:子父类方法要一模一样;
子类的实例化过程:
1, 在子类里面所有的构造函数默认第一行都会访问父类里的空参数构造函数;
2, 因为每一个构造函数的第一行都有一条默认的语句super();
3, 因为子类会具备父类中的数据,所以要明确父类是如何对这些数据初始化的;
4, 当父类里没有空参数的构造函数,子类构造函数必须通过this或者super语句指定要访问的构造函数。
final:最终。作为一个修饰符。
1, 可以修饰:类,函数,变量;
2, 为了避免方法被子类复写,所以被final修饰的类都不可以被继承;
3, 被final修饰的变量是一个常量,只能被赋值一次,成员变量和局部变量都可以修饰;
作为常量:书写规范是所以字母都大写,若多个单词组成之间用_连接。
4, 内部类定义在类中的局部位置上时,只能访问该局部被final修饰的局部变量。
例如:
class Demo{
final int x = 3;
public static final double PI = 3.14;//因为常量基本都是公有的所以可以加静态和public权限修饰
final void show1()
{}
void show2(){
final int y = 4;
System.out.println(3.14);
}
}
抽象类:abstract 关键字
定义:
将多个事物中共性本质内容抽取出来。
如:猫和狗都是动物,动物就是一个抽象类
当多个类出现相同的功能,但是功能主体不同,这时可以向上抽取,只抽取功能定义不抽取功能主体。
如:动物都有吃的方法,但是具体却是不同的,所以定义抽象的一个吃,具体的一个吃法需要子类复写抽象方法具体化。
抽象类的特点:
1, 抽象方法一定在抽象类中;
2, 抽象方法和抽象类都被关键字abstract修饰;
3, 抽象类不可以创建对象,因为调用抽象方法没意思;
4, 要想使用抽象方法,必须要子类复写所有的抽象方法后才建立子类对象调用,如果只是复写部分方法,那么子类还是一个抽象类;
例如:
abstract class Student{
abstract void study();
abstract void eat();
}
Class BaseStudent extends Student{
void study(){
System.out.println(“继承抽象类”);
void eat(){
System.out.println(“复写所以抽象方法”);
<span style="white-space:pre"> </span>}
}
抽象类练习:
*
假如我们开发一个系统时,需要对员工进行建模,员工包含3个属性:
姓名,工号,工资,经理也是员工,除了含有员工属性外,
另外还有一个奖金属性。请使用继承的思想设计出员工类和经理类
要求类中提供必要的方法进行属性访问。
*/
abstract class Person//定义一个抽象类{
private String name;
private int id;
private int gz;
Person(String name,int id,int gz)//构造函数初始化基本属性
{
this.name = name;
this.id = id;
this.gz = gz;
}
public abstract void work();//定义抽象方法,等待子类复写
}
class Worker extends Person
{
Worker(String name,int id,int gz)
{
super(name,id,gz);//使用super关键字,他和this关键字使用方法差不多,
}
public void work()
{
System.out.println("普工在车间");
}
}
class Manager extends Person
{
private int bonus;
Manager(String name,int id,int gz,int bonus)//构造函数初始化经理属性
{
super(name,id,gz);
this.bonus = bonus;//特有的属性需要this代表对象
}
public void work()
{
System.out.println("经理在办公室");
}
}
class AbsDemo
{
public static void main(String[] args)
{
Worker w = new Worker("zhnagsan",110,2300);
w.work();
Manager m = new Manager("lisi",001,5555,5000);
m.work();
}
}
模板方法模式:
定义:在定义功能时,功能有一部分是确定的,但是有一部分是不确定的,而确定的部分在使用不确定的,
那么这时就将不确定的单独暴露出去,有该类子类去完成。
通俗说呢,模板相当于烤面包的模子,他是已经定型的是确定的,但是要烤的面包材料不确定,需要我们自己添加。
举例子:
/*
需求:获取一段程序的运行时间,并请优化代码
原理:将程序开始时间和结束时间相减即可。
*/
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 TimeDemo extends GetTime
{
public void runCode()
{
for (int x = 0;x<2000 ;x++ )
{
System.out.print(x);
}
}
}
class AbsGetTime
{
public static void main(String[] args) //主函数
{
new TimeDemo().getTime();
}
}打印结果:
接口:
格式:interface {}
class是用于定义类的,
interface是定义接口的;
接口定义时的特点:
1, 常见定义:常量,抽象方法;
2, 接口中的成员都有固定的修饰符。
常量:public startic final;
方法:public abstract;
如:
interface Inter{
public static final int NUM = 3;
public abstract void show();
}
3,子类需要实现接口 用关键字:implements
接口特点
1, 接口是不可以创建对象的,因为有抽象方法;
2, 接口实际上就是程序功能的扩展;
3, 需要被子类实现,子类对接口中的抽象方法需要全部复写,子类才能实例化;
4, 接口可以被类多实现,这也相当于对多继承不支持的转换形式。
为什么接口可以多实现和多继承呢?
因为接口里面的抽象方法没有方法主体,不会影响子类调用。
---------------------- ASP.Net+Android+IOS开发、 .Net培训、期待与您交流! ----------------------详细请查看: http://edu.csdn.net