------- <a href="http://www.itheima.com" target="blank">android培训</a>、<a href="http://www.itheima.com" target="blank">java培训</a>、期待与您交流! ----------
面向对象
面向对象的特点:
是一种符合人们思考习惯的思想
可以将复杂的事情简单话
将程序员从执行者转换成了指挥者
完成需求时:
先去找具有所需功能的对象来调用
如果该对象不存在,那么创建一个具有所需功能的对象
这样简化开发并提高复用
开发的过程:其实就是不断的创建对象,使用对象,指挥对象的做事情
设计的过程:其实就是在管理和维护对象之间的关系
类与对象的关系
使用计算机语言就是在不断的描述现实生活中的事物
java中描述事物通过类的方式体现,类是具体事物的抽象,概念上的定义
对象既是该类事物实实在在存在的个体
成员变量和局部变量的区别
成员变量:
成员变量定义在类中,在整个类中都可以被访问
成员变量随着对象的建立而建立,存在于对象所在的堆内存中
成员变量有默认的初始化值
局部变量:
局部变量之定义在局部范围内,如函数内,语句内等
局部变量存在于栈内存中
作用的范围结束,变量空间会自动释放
局部变量没有默认的初始化值
匿名对象
匿名对象是对象的简化形式
匿名对象的两种使用形式:1,当对对象的方法仅进行一次调用时。2,匿名对象可以作为实际参数进行传递
封装(Encapsulation)
封装:是指隐藏对象的属性和实现细节,仅对外提供公共访问方式
好处:
将变化隔离
便于使用
提高了复用性
提高安全性
封装原则:
将不需要对外提供的内容都隐藏起来
把属性都隐藏,提供公共方法对其访问
面向对象的示例:
//需求:描述汽车(颜色,轮胎数)。描述事物其实就是描述事物的属性和行为
//属性对应类中的变量,行为对应类中的函数(方法)
//其实定义类,就是描述事物,就是在定义属性和行为。属性和行为共同称为类中的成员(成员变量和成员方法)
class Car
{
String color="red";
int num= 4;
void run();
{
System.out.println(color+"\t"+num);
}
}
class Cardemo
{
public static void main(String[] args)
{
Car c=new Car(); //类类型变量指向对象
//需求:将已有车的颜色改成蓝色
c.color="blue";
c.run();
//Car q= new Car();
//show(q);
//show(new Car());
}
//匿名对象的使用方式之一:当对对象的方法只调用一次时,可以用匿名对象来完成,这样比较简化。
// 如果对一个对象进行多个成员调用,必须给这个对象起个名字
//匿名对象使用方式之二:可以将匿名对象作为实际参数进行传递
/*
new char().num=5;
new char().color="blue";
new char().run();
Car c= new Car();
c.num=4;
c.run();
new Car().run();
*/
//需求:汽车修配厂,将来的车改装成黑色,三个轮胎
/*
public static void show(Car c)
{
c.num=3;
c.color="black";
c.run();
}
*/
}
//对象一建立就会调用与之对应的构造函数
//构造函数的作用:可以给对象进行初始化
//当一个类中没有定义构造函数时,那么系统会给该类加一个空参数的构造函数
//Person() {}
//当在类中自定义了构造函数时,默认的构造函数没有了
//什么时候定义构造函数呢?
//当分析事物时,该事物具备一些特性或者行为,那么将这些内容定义构造函数中
//需要未知内容参与运算,定义参数
class Pesron
{
private String name;
private int age;
/*
构造代码块:
给对象进行初始化
对象一建立就运行,而且优先于构造函数执行
构造代码块是给所有的对象进行统一初始化,而构造函数是给对应的对象初始化
*/
{
System.out.println("Person code run");
//定义不同对象的共性的初始化内容
cry();
}
//this: 就代表本类的对象,到底代表哪一个呢?
// this代表它所在函数所属的引用
//简单说:哪个对象在调用this所在的函数,this就代表哪个对象
Person()
{
System.out.println("A: name="+name+"\t"+" age="+age);
cry();
}
Person( String name)
{
this.name=name;
System.out.println("B: name="+name+"\t"+" age="+age);
cry();
}
Person( String name, int age)
{
//this.name=name;
this(name);
this.age=age;
System.out.println("C: name="+name+"\t"+"age="+age);
cry();
}
Person(int age)
{
this.age=age;
}
public void cry()
{
System.out.println("cry...........");
}
public String setName(String n);
{
name=n;
}
public String getName()
{
return name;
}
//需求:给人定义一个比较年龄是否相同的功能,也就是是否是同龄人
//this 的应用: 当定义类中功能时,该函数内部要调用该函数的对象时,这时用this来表示这个对象
//但凡本类功能内部使用本类对象,都用this表示
public boolean compare(Person p)
{
return this.age==p.age;
}
//this() 用于构造函数之间调用,只能定义在构造函数的第一行。因为初始化要先执行
//一般函数不能调用构造函数
}
class PersonDemo
{
public static void main(String[] args)
{
//Person p1= new Person();
//Person p2=new Person("zhangsan");
//Person p3=new Person("lisi",10);
Person p4= new Person(20);
Person p5= new Person(25);
boolaen b=p4.compare(p5);
}
}
/*
静态:static
用法:是一个修饰符, 用于修饰成员(成员变量,成员函数)
当成员被static修饰后,就多了一种调用方式,除了可以被对象调用外,还可以被类名调用。类名.静态成员
static特点:
1,随着类的加载而加载
也就是说静态会随着类的消失而消失,说明它的生命周期最长
2,被所有对象所共享
明确一点:静态是先存在,对象是后存在的
3,优先于对象存在
4,可以直接被类名调用
实例变量和类变量的区别:
1,类变量随着类的加载而存在于方法区中
实例变量随着对象的建立而寻在于堆内存中
2,生命周期:
类变量生命周期最长,随着类的消失而消失
实例变量的生命周期随着对象的消失而消失
3,主函数是静态的
静态的使用注意事项:
1,静态方法只能访问静态成员。
2,静态方法总不可以定义this,super关键字,以为静态优先于对象存在
静态有利有弊
利:对对象的共享数据进行单独的存储,节省内存,没有必要每个对象中都存储一份
可以直接被类调用
弊:生命周期过长,访问出现局限性(静态虽好,只能访问非静态)
*/
class Person
{
String name; //成员变量,实例变量
static String country="CN"; //静态变量,类变量
public void show()
{
System.out.println(name+": : :"+country);
}
}
class StaticDemo
{
public static void main(String[] args)
{
Person p=new Person();
p.name="zhangsan";
p.show();
System.out.println(Person.country);
}
}
/*
public static void main(String[] args)
主函数是一个特殊的函数,作为程序的入口,可以被jvm调用
public:代表该函数的访问权限是最大的
static:代表着随着类的加载已经存在
void:对主函数没有具体的返回值
main:不是关键字,但是可以被jvm所识别
(String[] args):函数的参数,参数类型是一个数组,该数组中的元素是字符串,字符串类型的数组
主函数是固定格式的:jvm只识别 public static void main(String[] args)。
*/
class MainDemo
{
public static void main(String[] args)
{
System.out.println(args);
}
}
/*
什么时候使用静态?
要从两个方面下手:
因为静态修饰的内容有成员变量和成员函数
什么时候定义静态的变量? 当对象中出现共享数据时,该数据被静态修饰
什么时候定义静态函数?
当功能内部没有访问到非静态数据(对象的特有数据)
那么该功能可以定义成静态
/*
静态的应用: 每一个应用程序中都有共性的功能
可以将这些功能进行抽取,独立封装,以便复用
*/
/*
public class ArrayTool
{
private ArrayTool() {}
public static int getMax()
{
int max=0;
for( int x=1; x<arr.length; x++)
{
if(arr[x]>arr[max])
max=x;
}
return arr[x];
}
public static int getMin()
{
int min=0;
for(int x=1; x<arr.length; x++)
{
if ( arr[x]<arr[min])
min=x;
}
return arr[min];
}
public static void selectsort(int [] arr)
{
for(int x=0; x<arr.length-1; x++)
{
for(int y=x+1; y<arr.length; y++)
{
if(arr[x]>arr[y])
{
awap(arr,x,y);
}
}
}
}
public static void bubblesort(int [] arr)
{
for( int x=arr.length-1; x>0; x--)
{
for(int y=0; y<x; y++)
{
if(arr[y]>arr[y+1])
{
swap(arr,y,y+1);
}
}
}
}
private static void swap( in [] arr, int x, int y)
{
int temp=arr[x];
arr[x]=arr[y];
arr[y]=temp;
}
public static void printArray(int [] arr)
{
System.out.prin("[");
for(int x=0; x<arr.length; x++)
{
if(x!=arr.length-1)
System.out.print(arr[x]+",");
else
System.out.println(arr[x]+"]");
}
}
}
*/
/*
虽然可以通过建立Arraytool的对象使用这些工具方法,对数组进行操作
发现了问题:
1,对象时用来封装数据的,可是Arraytool对象并未封装特有数据
2,操作数组的每一个方法都没有用到ArrayTool对象中的特有数据
这时就考虑,为了让程序更严谨,是不需要对象的
可以将ArrayTool中的方法定义为static的,直接通过类名调用即可
将方法都静态后,可以方便使用,但是该类还是可以被其他程序建立对象的
为了更为严谨,强制让该类不能建立对象
可以通过将构造函数私有化完成
*/
java说明书
//java的说明书通过文档注释来完成
/**
这是一个可以对数组进行操作的工具类,该类中提供了获取最值,排序等功能
@author 张三
@version V1.1
*/
public class ArrayTool
{
/**
空参数构造函数
*/
private ArrayTool();
/**
获取一个整型数组中的最大值
@param arr 接受一个int 型数组
@return 返回一个数组中的最大值
*/
public static int getMax(int [] arr)
{
int max=0;
for( int x=1; x<arr.length; x++)
{
if(arr[x]>arr[max])
max=x;
}
return arr[x];
}
/**
获取一个整型数组中的最小值
@param arr 接受一个int 型数组
@return 返回一个数组中的最小值
*/
public static int getMin(int [] arr)
{
int min=0;
for(int x=1; x<arr.length; x++)
{
if ( arr[x]<arr[min])
min=x;
}
return arr[min];
}
/**
给int 数组进行选择排序
@param arr 接收一个int 数组
*/
public static void selectsort(int [] arr)
{
for(int x=0; x<arr.length-1; x++)
{
for(int y=x+1; y<arr.length; y++)
{
if(arr[x]>arr[y])
{
awap(arr,x,y);
}
}
}
}
/**
给int 数组进行冒泡排序
@param arr 接收一个int 型数组
*/
public static void bubblesort(int [] arr)
{
for( int x=arr.length-1; x>0; x--)
{
for(int y=0; y<x; y++)
{
if(arr[y]>arr[y+1])
{
swap(arr,y,y+1);
}
}
}
}
/**
给数组中的值进行位置互换
@param arr 接收一个int型数组
@param x 要置换的位置
@param y 要置换的位置
*/
public static void swap( int [] arr, int x, int y)
{
int temp=arr[x];
arr[x]=arr[y];
arr[y]=temp;
}
/**
用于打印数组中的元素。打印形式是[element 1,element 2,...]
*/
public static void printArray(int [] arr)
{
System.out.prin("[");
for(int x=0; x<arr.length; x++)
{
if(x!=arr.length-1)
System.out.print(arr[x]+",");
else
System.out.println(arr[x]+"]");
}
}
}
/*
一个类中默认会有一个空参数的构造函数
这个默认的构造函数的权限和所属的类一致
如果类被public修饰,那么默认的构造函数也带public修饰符
默认构造函数的权限是随着类的变化而变化的
*/
单例设计模式:
/*
设计模式:解决某一类问题最行之有效的方法
java中有23中设计模式
单例设计模式:解决一个类在内存中只存在一个对象。
想要保证对象唯一
1,为了避免其他程序过多建立该类对象。先禁止其他程序建立该对象
2,还为了让其他程序访问到该对象,只好在本类中自定义一个对象
3,为了方便其他程序对自定义对象的访问,可以对外提供一些访问方式。
这三步怎么用代码体现?
1,将构造函数私有化
2,在类中创建一个本类对象
3,提供一个方法可以获取该对象
对于事物该怎么描述,还怎么描述
当需要该事物的对象保证在内存中唯一时,就将以上的三步加上即可
*/
class Single
{
private int num;
public void setNum(int num)
{
this.num=num;
}
public int getNum()
{
return num;
}
private Single() {}
private static Single s=new Single();
public static Single getInstance()
{
return s;
}
}
class SingleDemo
{
Single s1=Single.getInstance();
Single s2=Single.getInstance();
s1.setNum(23);
//Single s1= new Single();
//Single s2= new Single();
//s1.setNum(30);
System.out.println(s2.getNum());
}
/*
这个是先初始化对象
称为:饿汉式
Single类,一进内存,就已经创建好了对象
*/
class Single
{
private Single() {}
private static Single s =new Single();
public static Single getInstance()
{
return s;
}
}
*/
//对象是方法被调用时,才初始化,也叫做对象的延时加载。
//称为:懒汉式
//Single类进入内存,对象还没有存在,只有调用了getInstance时,才建立对象
//定义单例,建议使用饿汉式
class Single
{
private Single() {}
private Single s = null;
public static Single getInstance()
{ if(s==null)
{
Syschronise(Single.class)
{
if(s==null)
s=new Single();
}
}
return s;
}
}
class
静态代码块
/*
静态代码块
格式:
static
{
静态代码块中的执行语句
}
特点:随着类的加载而执行,只执行一次,并优先于主函数。
用于给类进行初始化
*/
class StaticCode
{
static
{
System.out.println("a");
}
public static void show()
{
System.out.println("show run");
}
}
class StaticCodeDemo
{
static
{
System.out.println("b");
}
public static void main(String[] args)
{
//new StaticCode();
//new StaticCode();
//System.out.println("over");
StaticCode s = null ;
s = new StaticCode();
StaticCode.show();
}
static
{
//System.out.println("c");
}
}
对象的初始化过程
Person p= new Person("zhangsan",20);
该句话做了什么事情?
1,因为new用到了Person.class,所以会找到Person.class文件并加载到内存中
2,执行该类中的static代码块,如果有的话,给Person.class进行初始化
3,在堆内存中开辟空间,分配内存地址
4,在堆内存中建立对象的特有属性,并进行默认初始化
5,对对象进行显示初始化
6,对对象进行构造代码块初始化
7,对对象进行构造函数初始化
8,将内存地址付给栈内存的p变量