面向对象
区别:面向过程思想,强调的是过程(动作)。
面向对象思想,强调的是对象(实体)。过程封装在实体中。(C++、Java、C#)
特点:
1.面向对象就是一种常见的思想,符合人们的思考习惯
2.面向对象的出现,将复杂的问题简单化
3.面向对象的出现,让曾经在过程中的执行者,变成了对象中的指挥者
特征:封装、继承、多态
类与对象的关系
类:事物之间的描述;
对象:该类事物的实例。在Java中是通过new来创建的。
Java语言对现实生活中的事物进行描述,是通过类的形式来体现的。
对于事物描述通常只关注两个放米娜:一个是属性,一个是行为。
只要明确该事物的属性和行为并定义在类中结课。
对象:其实就是该类事物实实在在存在的个体。
成员变量和局部变量的区别:
1.成员变量定义在类中,整个类中都可以访问,
局部变量定义在函数、语句、局部代码块中,只在所属的区域有效;
2.成员变量存在于堆内存的对象中,
局部变量存在于栈内存的方法中;(笔记4 179行)
3.成员变量随着对象的创建而存在,随着对象的消失而消失,
局部变量随着所属区域的执行而存在,随着所属区域的结束而释放;
4.成员变量都有默认初始化值,
局部变量没有默认初始化值。
/* 描述小汽车 分析 1.属性 轮胎数、颜色 2.行为 运行 定义类,其实就是在定义类中的成员。 成员:成员变量<-->属性;成员函数<-->行为。 */ class Car { //封装的是数据,而不是类似num color的变量 //属性和行为都是类的成员 //属性 成员变量 int num; //默认初始化值为0 String color;//String是类,而不是关键字;默认初始化值为null //行为 成员函数 void run() { //int num=10;//在调用该方法时,栈内存中有num=10,则输出结果为10 System.out.println(num+"..."+color); } } class CarDemo { public static void main(String[] args) { //在计算机中创建一个car的实例,通过new关键字 Car c=new Car();//c就是一个类类型的引用变量,指向了该类的对象 c.num=4; c.color="blue"; c.run();//要使用对象中的内容,可以通过 对象.成员 的相识来完成调用 System.out.println("-------------------------------"); Car c1=new Car(); Car c2=new Car(); show(c1); show(c2); c1.run(); c2.run(); } //汽车改装厂 public static void show(Car c)//类类型的变量,一定指向对象,否则就是null { c.num=3; c.color="black"; } }
匿名对象,也就是没有名字的对象
new Car();//匿名对象,其实就是定义对象的简写格式
Car c=new Car();//这是有名字的对象
c.run();//一个对象对方法进行一次调用
可简化为
new Car().run();
使用方式
1.当对象对方法仅进行一次调用的时候,就可以简化成匿名对象
new Car().num=5;
new Car().color="green";
new Car().run();//结果为0...null
2.匿名对象可以作为实际参数进行传递
show(new Car());//此时show()方法中的形参c接收这个匿名对象
数据类型传递的方法
//基本数据类型参数传递 class Demo { public static void main(String[] args) { /* main进入栈,则x=3存在于栈内存中;show()经调用后弹栈,x=4随之弹栈 */ int x=3; show(x); System.out.println("x="+x);//输出结果为3 } public static void show(int x) { x=4; } } //引用数据类型参数传递 class Demo { int x=3; public static void main(String[] args) { Demo d=new Demo(); d.x=9; show(d);//show()存在于栈内存,d.x存在于堆内存,故show()弹栈之后d.x=4仍旧存在于堆内存中 System.out.println(d.x);//输出结果为4 } public static void show(Demo d) { d.x=4; } }
封装
是指隐藏对象的属性和实现细节,仅对外提供公共访问方式
在Java中最小的封装体是函数。
好处:
将变化隔离;
便于使用;
提高重用行;
提高安全性;
封装原则
将不需要对外提供的内容都隐藏起来;
把属性都隐藏,提供公共方法对其访问。
private
私有,是一个权限修饰符,用于修饰类中的成员
私有的内容,只在本类中有效,外界不能直接访问
注意:私有仅仅是封装的一种体现
/* 人: 属性: 年龄 行为: 说话 */ class Person { /* private 私有,是一个权限修饰符,用于修饰类中的成员 私有的内容,只在本类中有效,外界不能直接访问 注意:私有仅仅是封装的一种体现 */ private int age; public void setAge(int a) { //外界无法直接访问age,通过本方法对age进行访问 age=a; } public int getAge() { return age; } void speak() { System.out.println("age="+age); } } class PersonDemo { public static void main(String[] args) { Person p=new Person(); p.setAge(-20); p.speak(); } }
构造函数
构建创造对象时使用的函数
特点
1.函数名与类名相同
2.不用定义返回值类型
3.没有具体的返回值
作用
给对象进行初始化
注意
1.默认构造函数的特点
2.多个构造函数是以重载的形式存在的
创建对象都必须通过构造函数初始化
一个类中如果没有顶一个过构造函数,那么该类中会有一个默认的空参数的构造函数
如果在类中定义了指定的构造函数,那么类中的默认构造函数就没有了。
一般函数和构造函数的区别
构造函数:对象创建时,就会调用与之对应的构造函数,对对象进行初始化。
一般函数:对象创建后,需要函数功能时才调用。
构造函数:对象创建时,只调用一次。
一般函数:对象创建后,可以被调用多次。
什么时候定义构造函数?
在描述事物时,该事物一存在就具备的一些内容,这些内容定义在构造函数中
class Person { private String name; private int age; //定义一个Person的构造函数 Person ()//构造函数,而且是空参数的 { name="baby"; age=1; System.out.println("person run"); //return; //结束函数 } //有的孩子一出生就有名字 Person(String n) { name=n; } Person(String n,int a) { name=n; age=a; } public void speak() { System.out.println(name+":"+age); } public void setName(String n) { name=n; } } class ConsDemo { public static void main(String[] args) { Person p=new Person();//构造函数在对象创建时就运行(给对像初始化) p.speak(); Person p1=new Person("旺财"); p1.speak(); Person p2=new Person("小强",10); p2.speak(); } }
this关键字
当成员变量和局部变量重名,可以用关键字this来区分
this:代表当前对象。
this就是所在函数所属对象的引用。
简单来说,哪个对象调用了this所在的函数,this就代表哪个对象。
this也可以用于在构造函数中调用其他构造函数
注意:只能定义在构造函数的第一行。因为初始化动作要先执行。
只要在本类中使用了本类的对象,通常使用this
class Person { private String name; private int age; //定义一个Person的构造函数 Person ()//构造函数,而且是空参数的 { name="baby"; age=1; System.out.println("person run"); //return; //结束函数 } //有的孩子一出生就有名字 Person(String name) { this.name=name;//this.name是对象的name } Person(String n,int a) { this(name);//给该对象初始化name,对象间的调用,必须放在第一个语句 age=a; } public void speak() { System.out.println(name+":"+age); } public void setName(String n) { name=n; } /* 判断是否是同龄人 */ public boolean conpare(Person p) { return this.age==p.age;//this.age是p1的age,p.age是p2的age } } class ThisDemo { public static void main(String[] args) { //Person p=new Person("旺财"); //p.speak(); //Person p1=new Person("小强"); //p1.speak(); Person p1=new Person("aa",30); Person p2=new Person("cc",12); p2.conpare(p1); } }
static(静态)关键字
特点:
1.static是一个修饰符,用于修饰成员;
2.static修饰的成员被所有的对象所共享;
3.static优先于对象存在,因为static的成员随着类的加载就已经存在了;
4.static修饰的成员多了一种调用方式,就是可以直接被类名所调用;调用格式为类名.静态成员;
5.static修饰的数据是共享数据,对象中存储的是特有数据;
成员变量和静态变量的区别
1.两个变量的生命周期不同
成员变量随着对象的创建而存在,随着对象的被回收而释放;
静态变量会随着类的加载而存在,随着类的消失而消失;
2.调用方式不同
成员变量只能被对象调用,
而对于静态变量,可以被对象调用,也可以被类名调用;
3.别名不同
成员变量,也称为实例变量;
静态变量,又称为类变量(区别于类型变量);
4.数据的存储位置不同
成员变量数据存储在堆内存的对象中,所以也叫做对象的特有数据;
静态变量数据存储在方法区(共享数据区)的静态区中,所以也叫对象的共享数据;
static的使用情况
1.静态变量
当分析对象中所具备的成员变量的值都相同时,这时,这个成员就可以被静态修饰
只要数据在对象中都是不同的,那就是对象的特有数据,必须存储在对象中,是非静态的;
如果是相同的数据,对象不需要做修改,只需要使用即可,不需要存储在对象中,定义成静态的;
2.静态函数
函数是否用静态修饰,需参考一点,该函数功能是否访问到对象中的特有数据;
简单来说,从源代码看,该功能是否需要访问非静态的成员变量,
如果需要,该功能就是非静态的;否则,就可以将该功能定义为静态的;
当然,也可以定义为非静态的,但是非静态需要被对象调用,而仅创建对象,调用非静态的、没有访问特有数据的方法,该对象的创建时没有意义的。
静态代码块
随着类的加载而执行,而且只执行一次
作用
用于给类进行初始化
class StaticCode { static int num;//只能进行赋值 static {//不只能够赋值,还能够运算 num=10; num*=3; System.out.println("hhhh"); } void show() { System.out.println("show run"); } } class Person { private String name; {//构造代码块,不同于static代码块。可以给所有对象进行初始化,创建了几个对象就执行几次 //System.out.println("person run"); cry(); } Person()//构造函数是给对应的对象进行针对性的初始化 { name="baby"; //cry(); } Person(String name) { this.name=name; //cry(); } public void cry() { System.out.println("cry"); } public void speak() { System.out.println("name:"+name); } } class StaticCodeDemo { //static //{//在主函数之前执行(随着类的加载而执行) //System.out.println("a"); //} public static void main(String[] args) { //new StaticCode().show(); Person p1=new Person(); Person p2=new Person("旺财"); p1.speak(); p2.speak(); } }
※注意:
1.静态方法只能访问静态成员(非静态既可以访问静态,又可以访问非静态);
2.静态方法中不可以使用this或者super关键字(this代表对象,而静态方法存在时,对象尚不存在);
3.主函数是静态的;
class Person { String name;//成员变量,又叫做实例变量 static String country="CN";//静态变量,又叫做类变量。单独开辟空间存储country,被所有的对象所共享 //不仅可以被对象使用,也可以被类名访问 public void show() //如果使用static修饰,show()随着类的加载而存在,此时不存在对象,而name存在于对象中,故编译时会报错 { System.out.println(country+":"+name); //System.out.println(Person.country+":"+this.name); } } class StaticDemo { int num=4; public static void main(String[] args) { Person p=new Person();//p是类类型变量,区别于类变量 p.name="小强"; p.show(); System.out.println(p.country); System.out.println(Person.country); new StaticDemo().show(); } public void show() { System.out.println(num); } }
主函数特殊之处(public static void main(String[] args)
1.格式是固定的;
2.被jvm所识别和调用
public:因为权限必须是最大的;
static:虚拟机在调用主函数时不需要对象,直接用主函数所属类名调用即可;
void:主函数没有具体的返回值;
main:函数名,不是关键字,只是一个jvm识别的固定的名字;
String[] args:这是主函数的参数列表,是一个数组类型的参数,而且元素都是字符串类型;
class MainDemo { public static void main(String[] args) //new String[0],产生了数组实体,但是没有存储元素 { System.out.println(args);//[Ljava.lang.String;@bdb503 System.out.println(args.length);// 0 System.out.println(args[0]); } }
static (静态)关键字
当编译器编译时,如果该类中使用了其他类,编译器会在CLASSPATH下或当前目录下查找使用的类,
如果查找无此类,则继续查找与使用类的名字相同的*.java文件,并自动编译
class ArrayToolDemo { public static void main(String[] args) { int[] arr={4,8,2,9,72,6}; ArrayTool tool=new ArrayTool(); int max=ArrayTool.getMax(arr); int index=ArrayTool.getIndex(arr,10); System.out.println("max="+max); System.out.println("index="+index); } } /** 建立一个用于操作数组的工具类,其中包含着常见的对数组操作的函数,如:最值、排序等。 @author C.C. @version v1.0 */ public class ArrayTool { private ArrayTool(){};//该类中的方法都是静态的,所以该类不需要创建对象, //为了保证不让其他程序创建该类对象,可以将该类的构造函数私有化 /* 获取整型数组的最大值。 @param arr 接收一个元素为int类型的数组; @return 返回该数组中的最大元素值; */ public static int getMax(int[] arr)//没有访问到特有数据,需加static { int maxIndex=0; for (int x=1;x<arr.length ;x++ ) { if(arr[x]>arr[maxIndex]) maxIndex=x; } return arr[maxIndex]; } /** 对数组进行选择排序 @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]) swap(arr,x,y); } } } /** 用于给数组进行元素的位置指环 @param arr 接收一个元素为int类型的数组; @param a int; @param b int; */ private static void swap(int[] arr,int a,int b) { int temp=arr[a]; arr[a]=arr[b]; arr[b]=temp; } /** 获取指定的元素在指定数组中的索引 @param arr 接收一个元素为int类型的数组; @param key 要找的元素; @return 返回该元素第一次出现的位置,如果不存在,则返回-1; */ public static int getIndex(int[] arr,int key) { for (int x=0;x<arr.length ;x++ ) { if(arr[x]==key) return x; } return -1; } /** 将int数组转换成字符串 格式是:{e1,e2,...}; @param arr 接收一个元素为int类型的数组; @return 返回该数组的字符串表现形式 */ public static String arrayToString(int[] arr) { String str="["; for (int x=0;x<arr.length ;x++ ) { if(x!=arr.length-1) { str=str+arr[x]+","; } else str=str+arr[x]+"]"; } return str; } }
javadoc -d myhelp -author -version ArrayTool.java //在当前目录下创建myhelp目录存放
使用set classpath=.;c:\myclass //包含已存在的类