------ ASP.Net+Android+IO开发.Net培训期待与您交流! ------
总结内容来源于黑马毕老师的java基础教学视频
面向对象思想:面向对象是相对于面向过程而言,面向对象和面向过程都是一种思想,面向过程强调的是功能,而面向对象强调的是将功能封装进对象,强调具备功能的对象.面向对象是基于面向过程的.
例如我想和妈妈说话,我只要找到能帮助我实现该功能的手机,打给我妈妈的就可以了,至于电话是怎么操作的我不知道,我达到了跟妈妈说话的目的,这就是面向对象.在这里手机就是对象,打电话就是手机对象的其中一个功能,手机把打电话功能封装起来了.
从功能封装的角度讲,面向对象和面向过程一样,也是函数,但是面向对象可以将多个联系紧密的函数封装在一起,形成类,当你需要某个功能,只需要调用这个类建立一个对象,拿对象来调用这个功能就行了。
面向对象的开发,就是找对象使用,如果没有对象,就建立一个对象,而程序员要做的就是,找对象,使用对象,建立对象,维护对象之间的关系。
类和对象的关系.
类就是:对现实生活中事物的描述.
对象:就是这类事物,实实在在存在的个体.
描述事物其实就是在描述事物的属性和行为.
属性对应类中的变量,行为对应类中的函数(方法).
成员变量和局部变量.
作用范围:
成员变量作用于整个类中.
局部变量作用于函数中,或者语句中.
在内存中的位置:
成员变量:在堆内存中,因为对象的存在,才在内存中存在
局部变量:在栈内存中.
匿名对象:顾名思义,就是没有名字的对象,是对象的一种简写形式。
匿名对象特点:
1.可以调用属性,但没有意义;
2.调用方法有意义,但只能调用一次,若对一个对象进行多次成员调用必须给该对象建立引用;
3.可以作为参数传递给函数。
匿名对象练习
- class Car
- {
- //描述颜色
- String color = "红色";
- //描述轮胎数
- int num = 4;
- //运行行为
- void run()
- {
- System.out.println(color+".."+num);
- }
- }
- class CarDemo
- {
- public static void main(String[] args)
- {
- //匿名对象写法,下面每个语句都是一个单独的匿名对象,互不干扰
- new.Car().num = 5;//创建一个匿名对象,num=5
- new Car().color = "blue";//创建一个匿名对象,color="blue"
- new Car().run();//创建一个匿名对象调用该对象方法
- //匿名对象的使用方式一:当对对象的方法只调用一次时,可以用匿名对象来完成,比较简化.
- //如果对一个对象进行多个成员调用,必须给这个对象起个名字
- //匿名对象使用方法二:可以将匿名对象作为实际参数进行传递.
- Car q = new Car();
- show(q);
- //可以写成下面的匿名对象
- show(new Car());
- }
- //需求"汽车修配厂.对汽车进行改装,3个轮子,黑色.
- public static void show(Car c)
- {
- c.num = 3;
- c.color = "black";
- c.run();
- //上面语句在内存中的形式见下图
- }
- }
面向对象三个特征: 封装,继承,多态 .
封装:是指隐藏对象的属性和实现细节,仅对外提供公共访问方式.
好处:将变化隔离,便于使用,提高重用性,提高安全性.
封装原则:
将不需要对外提供的内容隐藏起来.
把属性隐藏,提供公共方法对其访问.
private:私有,权限修饰符:用于修饰类中的成员(成员变量,成员方法)
私有只在本类中有效.
将age私有化以后,类以外即使建立了对象以后,也不能直接访问.
但是人应该有年龄,那么就需要在person类中提供对应的访问age的方式.
注意:私有仅仅是封装的一种表现形式.最小权限.
之所以对外提供访问方式,就是因为可以再访问方式中加入逻辑判断语句.
对访问数据进行操作,提高代码健壮性.
封装练习:- class Person
- {
- private int age;
- public void setAge(int a)
- {
- if (a>0 && a<130)
- {
- age = a;
- speak();
- }
- else
- {
- System.out.println("非法年龄");
- }
- }
- 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(40);
- //p.speak();
- }
- }
特点:函数于类名相同,不用定义返回值类型,不可以写return语句
作用:给对象进行初始化.
注意:1.默认构造函数的特点.2.多个构造函数是以重载形式存在.
对象一建立就会调用与之相对应的构造函数.
构造函数的作用:可以给对象进行初始化.
当一个类中没有定义构造函数时,那么系统会默认
构造函数和一般函数在写法上有不同
在运行上也有不同,构造函数在对象一建立就运行,给对象初始化.
而一般方法是对象调用才执行,是给对象添加对象具备的功能.
一个对象建立,构造函数只运行一次.
而一般方法可以被该对象调用多次.
什么时候定义构造函数呢?
当分析事物时,该事物存在具备一些特性或者行为,那么将这些内容定义在构造函数中.
例子:
- class Person
- {
- private String name;
- private int age;
- //构造代码块,给对象进行初始化,对象一建立就运行,优先于构造函数执行.
- //和构造函数区别:构造代码块给所有对象进行初始化.
- //构造函数给对应的对象初始化.
- {
- System.out.println("构造代码块");
- }
- Person()
- {
- System.out.println("A:name="+name+",,age="+age);
- cry();
- }
- Person(String n)
- {
- name = n;
- System.out.println("B:name="+name+",,age="+age);
- cry();
- }
- Person(String n,int a)
- {
- name=n;
- age=a;
- System.out.println("c:name="+name+",,age="+age);
- cry();
- }
- void cry()
- {
- System.out.println("cry........");
- }
- }
- class PersonDemo1
- {
- public static void main(String[] args)
- {
- Person p = new Person();
- Person p1 = new Person("lisi");
- Person p2 = new Person("wangwu",33);
- }
- }
简单说,那个对象在调用this所在的函数,this就代表那个对象.
this的应用:当定义类中功能时,该函数内部要调用到调用该函数的对象时,
用this表示这个对象.
简单来说就是本类功能内部使用了本类对象,都用this表示.
例子:
- class Person
- {
- private String name;
- private int age;
- Person(String name)
- {
- this.name = name;
- }
- Person(String name,int age)
- {
- this.name=name;
- this.age=age;
- }
- void speak()
- {
- System.out.println("name="+name+" age="+age);
- }
- //需求:给人定义一个用于比较年龄是否相同的功能,也就是是否是同龄人
- public boolean compare(Person p)
- {
- return this.age == p.age;
- }
- }
- class PersonDemo2
- {
- public static void main(String[] args)
- {
- Person p1 = new Person("lisi",30);
- Person p2= new Person("zhangsan",40);
- boolean b = p2.compare(p1);
- System.out.println(b);
- }
- }
this关键字在构造函数间的调用
- /*
- this语句:用于构造函数之间的互相调用.
- this语句只能定义在构造函数的第一行,因为初始化要先执行.
- */
- class Person
- {
- private String name;
- private int age;
- Person()
- {
- }
- Person(String name)
- {
- this();//是在调用上面的Person()构造函数
- this.name = name;
- }
- Person(String name,int age)
- {
- this(name);//是在调用上面的Person(String name)构造函数
- this.age=age;
- }
- void speak()
- {
- System.out.println("name="+name+" age="+age);
- }
- }
- class PersonDemo3
- {
- public static void main(String[] args)
- {
- Person p1 = new Person("lisi",30);
- p1.speak();
- }
- }
用法:是一个修饰符用于修饰成员(成员变量、成员函数)
当成员被静态修饰后,就多了一个调用方式,除了可以被对象调用外,还可以直接被类名调用,
写法是:类名.静态成员
static特点:
1,随着类的加载而加载.
也就是说:静态会随着类的消失而消失,说明它的生命周期最长,不建议定义过多的静态变量
2,优先于对象存在.
明确一点:静态是先存在,对象是后存在.
3,被所有对象共享.
4,可以直接被类名调用.
实例变量和类变量的区别:
1,存放位置
类变量随着类的加载而而存在方法区中.
实例变量随着对象建立而存在于堆内存中.
2,生命周期:
类变量生命周期最长,随着类的消失而消失.
实例变量随着对象的消失而消失.
静态的使用注意事项:
1,静态方法只能访问静态成员(成员方法和成员变量)
非静态方法既可以访问静态也可以访问非静态
2,静态方法中不可以定义this,super关键字.
因为静态优先于对象存在.所以静态方法中不可以出现this.
静态的优缺点
优:对对象共享的数据进行单独空间存储,节省空间,可以被类直接调用.
缺:生命周期过长,访问出现局限性.(静态虽好,只能访问静态)
例子:- class Person
- {
- private String name;//成员变量,实例变量
- //都是中国人,国家是一样的,所以用static,被对象共享
- static String country = "china";//静态的成员变量,类变量
- void setName(String name)
- {
- this.name = name;
- }
- void getName()
- {
- System.out.println(this.name);
- }
- public void show()
- {
- System.out.println(name+" "+country);
- }
- }
- class StaticDemo
- {
- public static void main(String[] args)
- {
- Person p = new Person();
- p.setName("lisi");
- p.show();
- //类名直接调用static修饰的静态成员
- System.out.println(Person.country);
- }
- }
主函数的定义:
public:代表着该函数访问权限是最大的.
static:代表者函数随着类的加载就已经存在.
void:主函数没有具体的返回值.
main:不是关键字,但是是一个特殊的单词,可以被jvm识别.
(String[] args):函数的参数,参数类型字符串类型的数组,args是参数的意思,可以被更改
主函数是固定格式的
jvm在调用主函数时,传入的是new String[0];
例如:
- class MainDemo
- {
- public static void main(String[] args)//new String[]
- {
- String[] arr = new String[]{"haha","xixi","hehe","gaga"};
- MainTest.main(arr);
- }
- }
- class MainTest
- {
- public static void main(String[] args)
- {
- for (int x=0;x<args.length;x++)
- {
- System.out.println(args[x]);
- }
- }
- }
什么时候使用静态?
从两方面下手:
因为静态修饰的内容有成员变量和函数.
1.什么时候定义静态变量(类变量)呢?
当对象中出现共享数据时,该数据被静态修饰.
对象中的特有数据要定义成非静态.
2.什么时候定义静态函数呢?
当类中的函数(方法)没有访问到非静态数据(变量),
那么该功能可以定义成静态的.
例如:
- class Person
- {
- String name;
- public static void show()//这个函数没有访问类中的变量,就用static修饰
- {
- System.out.println("haha");
- }
- }
- class StaticDemo1
- {
- public static void main(String[] args)
- {
- Person.show();
- }
- }
静态的应用.
每一个应用程序中都有共性的功能,可以将这些功能抽取独立封装,以便复用.
虽然可以通过建立ArrayTool的对象使用这些工具方法,对数组进行操作.发现了问题.
1.对象是用于封装数据的,可是ArrayTool对象并未封装特有数据.
2.操作数组的每一个方法都没有用到ArrayTool对象中的特有数据.
这时就考虑,让程序更严谨,是不需要建立对象的.
可以将ArrayTool中的方法都定义成static,直接通过类名调用即可.
将方法都静态后,可以方便于使用,但是该类还是可以被其他程序建立对象.
为了更严谨,强制该类不能建立对象.
可以通过让构造函数private(私有化),强制该类不能初始化并建立对象.
能隐藏起来的方法都用私有化隐藏起来.
例子:
- class ArrayTool
- {
- private ArrayTool(){}
- public static void getMax(int[] arr)
- {
- int max = 0;
- for (int x = 1;x<arr.length;x++)
- {
- if (arr[x]>arr[max])
- {
- max = x;
- }
- }
- System.out.println("max="+arr[max]);
- }
- public static void getMin(int[] arr)
- {
- int min = 0;
- for (int x = 1;x<arr.length;x++)
- {
- if (arr[x]<arr[min])
- {
- min = x;
- }
- }
- System.out.println("min="+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])
- {
- swap(arr,x,y);
- }
- }
- }
- }
- public static void bubbleSort(int[] arr)
- {
- for (int x = 0;x<arr.length-1;x++)
- {
- for (int y = 0;y<arr.length-x-1;y++)
- {
- if (arr[y]>arr[y+1])
- {
- swap(arr,y,y+1);
- }
- }
- }
- }
- private static void swap(int[] arr,int a,int b)
- {
- int temp = arr[b];
- arr[b] = arr[a];
- arr[a] = temp;
- }
- public static void printArray(int[] arr)
- {
- for (int x = 0;x<arr.length;x++)
- {
- if(x == 0)
- System.out.print("["+arr[x]+",");
- else if(x == arr.length-1)
- System.out.print(arr[x]);
- else
- System.out.print(arr[x]+",");
- }
- System.out.println("]");
- }
- }
静态代码块:static {静态代码块执行语句};
特点:随着类的加载而执行,只执行一次,用于给类初始化,优先于主函数,只有用到了类中的内容才加载类,才执行静态代码块。
*执行顺序: 静态代码块--- 构造代码块---构造函数
示例:
- class StaticCode
- {
- static
- {
- System.out.println("a");
- }
- }
- class StaticCodeDemo
- {
- public static void main(String[] args)
- {
- new StaticCode();
- System.out.println("b");
- }
- static
- {
- System.out.println("c");
- }
- }
- //输出的结果为c,a,b,由此可判断静态代码块在内存中优先主函数加载.
对象初始化过程
Person p = new Person("zhangsan",20);
这句话都做了什么事情?
1.因为new用到了Person.class,所以会先找到Person.class文件并加载到内存中.
2.执行该类中的static代码块(如果有的话),给Person.class类进行初始化.
3.在堆内存中给new Person("zhangsan"20)开辟空间,分配内存地址.
4.在堆内存中建立对象特有属性,并进行默认初始化.
5.对属性进行显示初始化.
6.对对象进行构造代码块初始化.
7.对对象进行对应的构造函数初始化.
8.将内存地址给栈内存中的p变量.
对象调用成员过程,见下图
设计模式:解决一类问题最行之有效的方法
java中23种设计模式
单例设计模式
想要保证对象唯一.
1.为避免其他程序过多建立该类对象,先禁止其他程序建立该类对象.
2.还为了让其他程序可以访问到该类对象,只好在本类中,自定义一个对象.
3,为了方便其他程序对自定义对象的访问,可以对外提供一些访问方式.
这三步怎么用代码体现呢?
1.将构造函数私有化.
2.在类中创建一个本类对象.
3.提供一个方法可以获取到该对象
单例设计模式有两种: 懒汉式和 饿汉式
- //这个是先初始化对象称为:饿汉式
- //Single类一进内存,就已经创建好了对象.
- //饿汉式为常用形式
- class Single
- {
- private Single(){}
- private static Single s = new Single();
- public static Single getInstance()
- {
- return s;
- }
- }
- //这个是对象调用才初始化,也叫对象的延时加载,称为:懒汉式
- //Single类进内存,对象还没存在,只有调用了getInstance方法时才建立对象
- 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;
- }
- }
帮助文档(又叫API帮助文档)的制作:javadoc
制作帮助文档的类必须是public修饰的.
范例:
- /**
- 这是一个可以对数组进行操作的工具类,该类中提供了获取最值,排序等功能.
- @author TMking
- @version V1.1
- */
- public class ArrayTool
- {
- /**
- 空参数构造函数
- */
- private ArrayTool(){}
- /**
- 获取一个整形数组中的最大值
- @param arr 接受一个int类型的数组.
- */
- public static void getMax(int[] arr)
- {
- int max = 0;
- for (int x = 1;x<arr.length;x++)
- {
- if (arr[x]>arr[max])
- {
- max = x;
- }
- }
- System.out.println("max="+arr[max]);
- }
- /**
- 获取一个整形数组中的最小值
- @param arr 接受一个int类型的数组.
- */
- public static void getMin(int[] arr)
- {
- int min = 0;
- for (int x = 1;x<arr.length;x++)
- {
- if (arr[x]<arr[min])
- {
- min = x;
- }
- }
- System.out.println("min="+arr[min]);
- }
- /**
- 给一个整形数组进行选择排序
- @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类型的数组.
- */
- public static void bubbleSort(int[] arr)
- {
- for (int x = 0;x<arr.length-1;x++)
- {
- for (int y = 0;y<arr.length-x-1;y++)
- {
- if (arr[y]>arr[y+1])
- {
- swap(arr,y,y+1);
- }
- }
- }
- }
- /**
- 给数组中的元素进行位置置换.
- @param arr 接受一个int类型的数组.
- @param a 要置换的位置.
- @param b 要置换的位置.
- */
- private static void swap(int[] arr,int a,int b)
- {
- int temp = arr[b];
- arr[b] = arr[a];
- arr[a] = temp;
- }
- /**
- 打印数组中的元素,打印形式是:[element1,element2,...]
- @param arr 接受一个int类型的数组.
- */
- public static void printArray(int[] arr)
- {
- for (int x = 0;x<arr.length;x++)
- {
- if(x == 0)
- System.out.print("["+arr[x]+",");
- else if(x == arr.length-1)
- System.out.print(arr[x]);
- else
- System.out.print(arr[x]+",");
- }
- System.out.println("]");
- }
- }