第一篇:黑马程序员java培训就业班笔记:day10总结
Day10总结:
1、多态的特点:
1、成员变量:
当在子父类中出现了相同的非私有成员变量时,在多态调用中的特点:
在编译时:参考引用型变量所属类中是否有调用的成员变量,如果有编译通过,如果没有编译失败。
在运行时:参考引用型变量所属的类中的成员。
简单一句话:对于成员变量无论是编译还是运行都参考引用型变量所属类中的成员变量。
也就是说:成员变量看等号左边。
2、成员函数:
当子父类中出现一模一样的函数时,在多态调用中的特点:
在编译时:参考引用型变量的所属的类中是否有调用的成员函数。在运行时:参考的是对象所属的类中是否有调用的成员函数。
原因是:编译时期应该参考父类,运行时期应该参考子类。因为成员函数上有一个特点覆盖。
简单一句话:对于成员函数,编译看左边,运行看右边。
3、静态函数:
在编译时期:参考引用型变量所属的类中是否调用的静态函数,如果有编译通过,如果没有编译失败。
在运行时期:参考的还是引用型变量所属的类中的静态函数。简单一句话:对于静态函数,无论是编译还是运行都看左边
总结:对于多态成员而言,无论编译还是运行都看左边,只有成员非静态函数,编译看左边,运行看右边,因为覆盖的特性。
2、多态的应用: 代码实现:
Object:所有类的父类,该类中的方法所有对象都具备。代码实现:
Class Demo extends Object { Private int num;Demo(int num){ This.num=num;} 通常都会按照对象自身的特点对对象进行比较,比如:现在要比较两个Demo对象中null值是否相同。} Public boolean compare(Demo b){ Return this.num=d.num;
} 发现Demo继承Oject已经具备了比较对象的方法,所以没有必要再定义新的方法compare了,直接使用equals就可以了,可是Object equals比较的是地址值,不是我们所需的,那就保留的父类的功能声明,建立自身的比较内容,这就是覆盖。Public boolean equals(Object obj){ If(!(Object instanceof Deno))Return false;Demo d=(Demo)obj;向下转型。
Return this.num=d.num;此处体现了多态的特性。} Public String toString(){ Return “demo:”+num;} Class ObjectDemo { Public static void main(String[] args){ Demo d1=new Demo(4);Demo d2=new Demo(4);Sop(d1.toString());Sop(d1);Sop(c1.getName());Sop(d1.compare(d2));} }
4、内部类:
将一个类定义在另外一个类的里面的类称为内部类 当一个类要直接访问另外一个类的成员时,可以将这个类定义到另一个类里面,称为另一个类的内部类。
内部类访问的规则:
1、内部类可以直接访问外部类中的成员。
2、外部类需要创建内部类对象才可以访问内部类中的成员。
在描述事物时,事物中还有具体的事物时,而且这个内部事物在访问着外部的事物时。这时对这个内部事物的描述,就可以用内部类完成。
内部类出于外部类的成员位置上是可以被成员修饰符所修饰的。Public
Private:将内部类私有化时,只能对外提供方法,对内部类的控制。
Static:当内部类中定义了静态的成员时,该内部类必须静态的,否则编译失败。代码体现: Class Outer { Static int num=4;Static class Inner //内部类,为什么要定义内部类?
当一个类要直接访问另一个类中的成员时。可以将这个类定义到另一类里面。{ Static void show(){ Sop(“show run”+num);} Public void method(){ Inner in=new Inner();In.,show();} } } Class InnerClassDemo { Public static void main(String[] args){ //Outer out=new Outer();
//out.method();
//System.out.println(“Hello World!”);
//当访问一个外部类的内部类时,先由外部类对象再有内部类对象。
//Outer.Inner in=new Outer().new Inner();//要指明内部类所处的外部类
//in.show();
//内部类静态化,要调用的非静态的方法show();
//Outer.Inner in=new Outer.Inner();
//in.show();
//如果show方法也是静态的,要调用静态的方法show();
Outer.Inner.show();} }
5、匿名内部类:没名字的内部类。
就是内部类的简化写法。
前提:内部类可以继承或者实现一个外部类。代码实现: 格式:
New 父类名or 接口名(){子类的具体内容} Abstract class AbdsDemo { Abstract void show1();Abstract void show2();} Class Outer { Int num=4;New AbsDemo(){ Void show()//匿名内部类 { Sop(“num===”+num);} }.show();} Public void method2(){ AbsDemo a=new AbsDemo();{ Public void show1();Public void show2();};A.show1();A.show2();//要想调用两个方法,怎么做?起个名称即可
当里面有多个方法的时候建议不要写匿名内部类。
}
-----------------------------interface Inter {
void show();} class Outer {
//补足代码。最好用匿名内部类
static Inter method()//为什么是Inter类型
{
return new Inter()
{
public void show()
{
System.out.println(“show run”);
}
};
} }
class InnerClassTest
{
public static void main(String[] args)
{
Outer.method().show();
/*
Outer.method():Outer类中有一个method方法,而且这个方法是静态的。
Outer.method().show
会返回一个对象,而且这个对象还可以调用show方法
说明这个对象肯定是Inter类型。
*/
} }
------------------------------
6、异常:
是在运行时期发生的不正常情况
Java发现不正常的情况都包含着一些常见信息,并 将这些信息进行了对象的封装。异常这种机制,其实就是java按照面向对象的思想将出现的问题封装成了对象。在进行问题分析时,发现问题有很多种,但是不断向上抽取,最终问题可以归纳为两种,一种是可以针对处理的一种是通常不进行处理的。
在java中的体现一个是Exception ,一个是Error,后者一般针对处理。
无论是异常还是错误,他们都有名称信息等共性的内容。
可以继续抽取形成一个父类:throwable可抛出。Throwable
|---Error |---Exception 异常和错误都有一个特点:其子类的名称的后缀名都是父类名。
该体系具备一个特殊的特性叫做可抛性,该体系中的类可以被关键字throws抛出。
该体系中的类产生的对象可以被Throw抛出,简单说该体系可以被Throws 和throw操作。
Throw 和throws的区别:
Throws:定义在函数上,用于声明函数的可能出现的问题,后面跟异常类,可以跟多个,用逗号隔开、Throw:定义在函数内,用于抛出异常对象因为程序的跳转,后面跟的是异常对象。
If判断和异常处理的区别:
If判断是将正常代码和异常代码写在一起。阅读性极差,异常处理将问题代码和异常处理代码分离。代码实现: Class Demo { 功能的定义着在定义工呢过时,发现该功能容易因为未知内容的不确定性的出现的问题。为了让调用者明确,有可能有问题,需要在函数上对问题进行声明。
需要一关键字throw异常名。
Int p(int a,int b)throws Exception//抛出异常是为声明异常问题,让调用者去处理。{ If(b==0)Throw new ArithmeticException(“除数为零、违反规则”);
Return a/b;} } 对异常的针对性处理方式: Try { 需要被检测的代码; } Cathch(异常类 变量){ 异常处理代码 } Finaly { 一定会被执行的代码。}
自定义异常:
Java将常见的问题都封装成了对象。
对于自定义项目中出现的问题,java并未给出对应的描述,这时我们就需要按照面向对象的思想自己完成对问题的描述和封装。
自定义异常:
需求:在我的程序中,进行除法运算,除数不可以为负数也不可以为0;对0这种情况,java中有对应的描述,ArithmeticException 对于负数,java中没有。只有我们自己定义,定义一个类来对异常进行描述。
Class FuShuException extends Exception { Private int num;FuShuException(){} FuShuException(String message,int num){ Super(message);This.,num=num;} Public int getNum(){ Return num;} } Class Demo { Int p(int a,int b)throws FuShuException { If(b<0)Throw new FuShuException(“除数不可以为负数”);函数内抛出异常,函数上一定要标示。函数内抛出是什么?函数上就标示什么? 对方抛出什么异常,我就处理什么异常。Return a/b;} }
Class ExceptionDemo2 { Public static void main(String[] aths){ Demo d=new Demo(); Try
{ Int num=d.p(4,-1);Sop(“num=”+num);} Cathc(FuShuException e){ Sop();e.printStackTrace();} Sop(“over”);} }
自定义应用: 异常分两种:
1、编译被检测的异常:Exception 这种异常通常都需要进行针对性的处理。
2、运行时发生的异常:RuntimeException 对于运行时异常一般是不编写针对性的处理方式,如果该异常发生就让程序停止,对程序进行修正。因为这种的出现往往已经无法让程序继续运算了。
class Demo {
int p(int a,int b)throws ArithmeticException
{
if(b==0)
throw new ArithmeticException(“除数为零”);
return a/b;
} } class ExceptionDemo3
{
public static void main(String[] args)
{
getIndex(null,4);
}
public static int getIndex(int[] arr,int key)
{
if(arr==null)//进行健壮性判断。
throw new NullPointerException(“没有具体的数组”);
for(int x=0;x
{
if(arr[x]==key)
return x;
}
return-1;
}
public static int getElement(int[] arr,int index)
{
if(arr==null)
throw new NullPointerException(“没有具体的数组实例”);
if(index<0||index>=arr.length)
throw new ArrayIndexOutOfBoundsException(“角标越界”);
return arr[index];
} }-------------------异常练习:
/* 需求:
毕老师用电脑上课。按照面向对象思想来描述。名词提炼法
上课过程中出现的问题:
1、电脑蓝屏了。
2、电脑冒烟了。
*/ class LanPinException extends Exception {
LanPinException(String message)
{
super(message);
} } class MaoYanException extends Exception {
MaoYanException(String message)
{
super(message);
}
} class NoPlanException extends Exception {
NoPlanException(String message)
{
super(message);
} } class Computer {
private int state=2;
public void run()throws LanPinException,MaoYanException
{
if(state==1)
throw new LanPinException(“电脑蓝屏了”);
if(state==2)
throw new MaoYanException(“电脑冒烟了”);
System.out.println(“电脑运行”);
}
public void reset()
{
System.out.println(“电脑重启”);
state=0;
} } class Teacher {
private String name;
private Computer cmpt;
Teacher(String name)
{
cmpt=new Computer();
this.name=name;
}
public void prelect()throws NoPlanException//此处冒烟是电脑发生的,能再老师讲课的功能出现这样的异常么?所以抛出的对象不对,老师只能耽误了讲课的进度,所以此时是否应该定义一个关于讲课进度的类来封装这个问题。
{
try
{
cmpt.run();
System.out.println(name+“毕老师讲课”);
}
catch(LanPinException e)
{
System.out.println(e.getMessage());
cmpt.reset();
prelect();
}
catch(MaoYanException e)//这个功能我处理不了,因为冒烟不会了,这时候需要抛出。
{
test();
//throw e;//因为处理不了,继续往外抛。此时在讲课方法上要声明。此处也不能抛出这个异常。因为冒烟是电脑运行时的,不是老师讲课的。
throw new NoPlanException(“课时无法继续进行”);
}
}
public void test()
{
System.out.println(“练习”);
} } class ExceptionTest {
public static void main(String[] args)
{
Teacher t=new Teacher(“毕老师”);
try
{
t.prelect();
}
catch(NoPlanException e)
{
System.out.println(“换人”);
}
} } //到底什么是抛什么处理?
/*
自己能解决的就处理,处理不了就抛。
比如着火了,小火的时候自己可以处理,比如灭火器等
当火势大了,就处理不了,只能交给消防队,自己要跑。
*/
第二篇:黑马程序员java培训就业班笔记:day05总结
Day05 上午:
1、数组的静态初始化
多种定义格式:
Int[] arr=new int[]//标准格式,可以明确数组的数据类型,和数组名,但是不知道数组的长度
Int arr[]=new int[] Int[] arr=new int[]{2,1,3,4,5,}//通过大括号可以标示出数组中的内容,此处最好别写长度,因为容易出错,因为即初始化实体,又初始化实体中的元素。
Int[] arr={2,1,3,4,5};//可以明确数组的数据类型,和数组名,也可以知道数组中的内容。
2、arr.length:方便获取数组中的元素个数的方式。
3、操作数组的最基础的思想以及核心思想:
a)最基础的思想:就是遍历。什么是遍历。
Eg:int[] arr = new int[3];int[] arr = {4,8,9,2,6,9};//明确了数组的类型和长度,并明确了数组中元素的内容。
// int[] arr1 = new int[]{4,8,9};//方便获取数组中的元素个数的方式,可以使用数组实体一个属性。length System.out.println(“len:”+arr.length);
for(int x=0;x
if(x%2==1)
System.out.println(“arr[”+x+“]=”+arr[x]);//arr[0] = 4;}
这就是遍历的思想,获取数组中的元素,通常会用到遍历。
b)核心思想:就是操作数组中元素的角标,角标即索引,因为存数据的最终目的就是取出数据使用,就是操作角标,操作动作:
1、给数组角标上的元素赋值,2、获取角标上元素的值,存储都得用角标
4、数组中常见的操作:
a)获取最值:
思路:
1、首先我们要定义一个功能完成获取数组中最大值的动作;
2、定义个函数来实现这一功能;明确结果,整数数组中的最大值,int,明确是否有未知内容参与运算,参数列表中有一个参数,数组类型int[],一定要注意这里是数组类型,不是int型;
3、如何实现功能细节呢?
1、对数组中的元素进行比较,将比较后比较大的值进行记录,并参与下一次比较,当数组中的元素都比较完成后,最大值就已经被记录下来了。
2、每次比较的较大的值不确定,定义一个变量进行记录,该变量如何初始化呢?只要初始化为数组中的人一个元素即可。
3、应该让数组中的元素自动和该变量记录的元素进行比较,所以可以使用遍
历,获取数组中的每一个元素。
4、当遍历到元素比较变量中的记录的元素大,用该变量记录住更大的元素。
5、遍历结束后,变量存储就是数组中的最大值。实现代码:eg:
Public static int getMax(int arr){ /.定变量记录较大的值;
Int max=arr[0];//初始化数组中的任意个元素; //对数组进行遍历比较
For(int x=1;xmax)
Max=arr[x];} Return max;} 同样有另外一种方式获取最大值 Public static int getMax(int[] arr){ Int maxIndex=0;//初始化为数组中一个元素的角标 For(int x=1;xarr[maxIndex])
maxIndex=x;} Return arr[maxIndex];} b)排序:
1、选择排序:
首先通过数组中元素的比较方式来分析:
用数组中第一个角标的元素与数组中第二个角标的元素进行比较,发现9比6大,进行位置置换,此处应该定义一个三方变量,用来记录住置换过程的元素值,然后再用第一个角标的元素与下一个角标元素进行比较,按照全面的原则进行置换位置,如果前者小于后者,则不置换位置,一次比较,当第一轮结束之后第一个角标出能取的该数组中最小的元素的值,然后再用第一个角标的元素开始和下一个角标的元素进行比较,同理,当第二轮结束后,第二个角标处获取了该数组中的第二小的值。所以我们发现当依次这样比较下去,就可以对数组中的元素进行排序,当比较到arr.length-1元素时,发现只剩下这一个元素,没有其他元素和它进行比较了。思路:
1、首先定义一个功能函数对数组进行排序,2、明确结果,没有返回值,因为它只是对数组进行排序的一个动作,明确是否有未知内容参与运算,有,数组类型int[] arr 实现代码:
Public static void selectSort(int[] arr){ For(int x=0;x
if(arr[x]>arr[y]){
Int temp=arr[x];Arr[x]=arr[y];Arr[y]=temp;} } }
}
优化后的选择排序:
从上面的排序图中我们可以知道,对数组中元素进行置换位置的次数过多,也就是对堆内存的操作频繁,降低了性能,下面我们可以通过这种方式对性能优化。
思路:
在栈内存中我们定义两个变量,分别用来记录较小的元素的值和较小元素的角标,然后对其进行初始化,至于初始化的值只要是数组中的任意元素即可,然后拿数组中的元素与它进行比较,如果发现拿去比较的元素比变量中记录的数值要小,那么就进行位置置换,并记录下较小的元素的角标,依次把数组中的元素遍历完,就可以获取数组中的最小元素的值和角标,然后我们拿初始化的值和获取的最小的元素进行位置的置换,这样以来当我们获取了数组中的元素的最小的时候,堆内存中的只用操作一次位置即可,这样的就提高性能。实现代码:
Public static void selectSort_2(int[] arr){ For(int x=0;xarr[y])
Num=arr[y];Index=y;} If(index!=x){ int temp = arr[x];arr[x] = arr[index];arr[index] = temp;
} } } 注意:复习的时候添加注释
2、冒泡排序:
首先通过排序方式来分析其步骤:
通过排序方式,可以知道是用数组中的元素挨个比较,如果前面的元素的值比它下一个角标的元素大,则进行位置置换,然后再用第二个角标的元素与下一个角标的元素进行比较,同样如果下一个角标的元素比它小,则进行位置置换,这样当比较到arr.length-1个元素时已经没有 和它进行的比较的元素了,当第一轮比较结束后,我们可以知道最后一个角标的元素为该数组中的最大值,按照同样的原理进行下一次比较,依次获取了比较大的元素的值。
实现代码:
Public static void bubbleSort(int[] arr){ For(int x=0;x
If(arr[y]>arr[y+1]){
//位置置换 } } } }
c)折半查找:
首先分析数组元素的查找方式:
首先要明确数组时有序的。
首先定义三个变量min、mid、max分来用来记录最小角标、中间角标、最大角标,中间角标的获取为(min+max)/2;获取中间角标之后,就可以获取中间角标对应的元素arr[mid];用我们所需要查找的key与中间角标运算进行比较,如果key>arr[mid];那么此时min的位置就是mid的下一个角标,min=mid+1;然后再次获取中间角标的元素,mid=(min+max)/2,同时也获取了中间角标对应的数组元素,arr[mid],然后同理,拿key与中间角标的元素进行比较.同样的原则,依次比较,直到key==arr[mid]的时候获取key.如果当出现了min>max或者时候则说明我们要查找的key在该数组中布存在,return-1;
实现代码:
Public static void binarySearch(int[] arr int key){ Int min,mid,max;Min=0;Max=arr.length-1;Mid=(min+max)>>1//相当于/2,右移的效率比它要高 While(arr[mid]!=key){ If(key>arr[mid])Min=mid+1;Else if(key
Min=mid-1;If(max
Return mid;} 注意:复习的添加代码注释
总结:折半查找也称二分查找,这种查找可以提高效率,但是被查找的数组的额元素必须是有序的。不能对无序的数组进行排序后再用折半查找,因为这时候数组中元素的角标已经发生变化了。
5、查表法思想:
a)什么时候使用查表法?
当元素很多,而且这些元素与数组有对应关系,而且这些数字都有角标的规律的时候。
扩展:什么时候使用数组?
当同一类型的元素较多时,就使用数组这个容器对数据进行存储。b)查表法思想的代码体现:
0 1 2 3 4 5 6 7 10 11 12 13 14 15 '0', '1', '2', '3', '4','5', '6',' 7', '8', '9','A',' B', 'C' ,'D', 'E' ,'F' 我们发现十六进制中一共有16个元素,而且每通过&15获取的数字都再15之内,都有对应的十六进制元素,而且元素对应的数字正好有规律,而且符合了数组这种容器的特点角标,那么可以将十六进制的元素都存储到数组中,将每次&15的结果作为角标去查这个数组,就可以获取到十六进制的对应的元素。这就是查表思想。
代码体现:
Public static void searchList(int num){ //定义一个十六进制的元素表
Char[] arr={'0', '1', '2', '3', '4','5', '6',' 7', '8', '9','A',' B', 'C' ,'D', 'E' ,'F'};//定义一个char类型元素的数组,用于存储每次获取到的十六进制值。Char[] chs=new char[8];Int pos=chs.length;While(num!=0){ Int temp=num&15;Chs[--pos]=arr[temp];Num=num>>>4;} For(int x=pos;x 通过上面我们可以知道那么是否可以定义这样的一个功能函数呢?用来对十进制、二进制、八进制、十六进制进行转换? 思路: 1、明确结果,没有返回值,只是对给定的数据转换的功能。 2、明确是否有未知内容参与运算,有,是什么?求的数值num,十六进制是&15,八进制是&7,二进制是&1,那么&的这个是不确定的,我们定义为变量 base,当这个数值通过&上这些数据后,要取出后面的数值,我们通过右移来实现,但是各个进制的不一样右移的位置数也是不一样的,十六进制是无条件右移四位,八进制是无条件右移三位,二进制是无条件右移1位,所以这个数也是不确定的,定义变量 offset 实现代码: //十进制--二进制 public static void toBin(int num){ trans(num,1,1);} //十进制--八进制 public static void toOctal(int num){ trans(num,7,3);} //十进制--十六进制 public static void toHex(int num){ trans(num,15,4);} Public static void trans(int num,int base,int offset){ If(num==0){ Sop(0);;Return;} //定义一个十六进制的元素表 Char[] arr={0', '1', '2', '3', '4', '5', '6', ' 7', '8', '9', 'A',' B', 'C' ,' D', 'E' ,'F'};Char[] chs=new char[32];Int pos=chs.length;While(num!=0){ Int temp=num&base;Chs[--pos]=arr[temp];Num=num>>>offset;} For(ingt x=pos;x System.outr.println(chs[x]);} } 注意:复习的添加代码注释。 这一章节自己还不是很熟悉,能理解,但是不能独立写出代码,在以后的几天内要每天都要一遍,并自己独立写出代码,做到思想理解透彻。先要产生一天的宏观思想。复习方法: 首先总结当天学习的方法。遇到不会的先放到一边。每天晚上睡着觉之前要回忆一遍。 Day06总结: 上午 1、二维数组 格式: Int[][] arr=new int[2][3];[2]代表1维数组的个数; [3]代表1维数组有三个元素; 内存图: 分析: 通过对内存图分布可知,首先在栈内存中加载main函数,开辟空间,定义一个变量arr,在堆内存中通过New创建一个数组实体int[2],并分配其地址值为0x0045,数组元素值进行默认初始化为Null;然后把地址值赋值给栈内存中的arr.在堆内存中开辟两块空间,分别用来存放二维数组中的数组元素,分配其地址值分别为0x0056、0x0089,然后对将地址值传给二维数组中的元素,所以说对内存中二维数组存储的是一维数组的地址值。最后变量通过二维数组的地址0x0045指向二维数组。 注意:二维数组中必须指定长度、以及实体没有对二维数组进行初始化时默认为null; 2、对二维数组的遍历(大圈套小圈思想)For(int x=0;x 3、面向对象的理解: 特点: 1、面向对象就是更符合人们思考习惯的一种思想。 2、从面向过程的执行者,转变成了面向对象的指挥者 3、面向对象将复杂的事情简单化了。 其实面向对象是一种思想,是面向过程而言,将复杂的事情变的更简单了。通过把大象放到冰箱里这个列子来理解面向对象的概念 面向过程:把冰箱门打开、存储大象、关闭冰箱;强调的过程注重行为; 面向对象:冰箱.打开、冰箱.存储、冰箱.关闭;强调的是冰箱这个对象。 面试题:你怎么理解面向对象? 首先说面向对象的特点:它是一种思想,它让复杂的问题简单化,它把执行者变成了指挥者。 然后举例子来说明,最牛的就是结合实际场景来说:其实面试官你就是在用面向对象的思想在思考问题,为什么这么说?因为公司业务蒸蒸日上,需要招更多的人来完成项目,所以才在这里招聘人员,你需要找一些具备专业编程经验的人,来帮公司完成工作,那么我就是那个对象,因为我具备专业编程能力,你就是那个指挥者,指挥我来做事,至于我怎么去完成编程任务,你是不需要去知道,你只要结果了就可以了,这其实就是把你之前的工作简化了,你不必再事必躬亲了。这就是面向对象思想的体现。 同时可以结合去饭店吃饭,在家做事等等列子来说明面向对象的思想。 扩展:OOP:面向对象编程。 OOA面向对象分析。 OOD:面向设计。还有面向接口、面向框架、面向对象的语言:C++、JAVA、C# 4、在实现功能,先找java当中是不是提供好了相关的对象,没有对象自己造一个对象。比如说公司招聘人员找不到人的时,这时公司就需要自己在公司内部培养人,也就是自己造对象。 5、类和对象关系: a)类到底是什么? 类就是对现实生活中事物的描述,描述中包含了该类事物的共性内容。Class Car(){ Int num;String color;Void run(){} } 在类中定义的变量和函数都称为类中的成员。成员: 成员变量---属性 成员函数---行为 b)什么是对象? 对象就是该类事物实实在在存在的个体。 Eg:现实生活中的对象:张 三、李四 想要描述:提取对象中的共性内容,对具体的抽象。 描述时:这些对象的共性有姓名年龄性别学习java的功能。对象也可以理解为其实就是个容器,用来存储更多的数据,存储的都是每一个对象特有的数据,而类就是这些数据所属的属性。 用java语言来描述一个小汽车 描述事物:无非就是描述事物的属性和行为 属性:轮胎数、颜色 行为:运行 Eg: Class Car { String color=“red”;Int num=4;Run(){ System.out.println(color+“"+num);} } Class CarDemo { Public static void main(String[] args){ Car c=new Car();C.color=”bule“;C.num=5;C.run();m Car c1=new Car();C1.num=8;C1.color=”green“;C1.run();} } 重点:分析上述代码在内存中的分布: 复习的时候写内存分析: 6、成员变量和局部变量的区别: 1、源代码中定义位置不同: 成员变量:定义在类中,在整个类中有效。局部变量:定义在函数中,在局部范围内有效。简单一句话:作用范围不一样,成员变量作用于整个类中,局部变量作用于函数中,或者语句中。 2、在内存中的位置和事件不同: 生命周期不同: 成员变量:随着对象的创建的而出现在堆内存中,随着对象被回收而消失。 局部变量:随着变量所属局部区域的运行,而出现在栈内存中,随着所属区域运行结束而释放。 3、变量使用的初始化: 成员变量:因为堆内存中都有默认初始化值,对于引用型变量默认值就是null;局部变量:因为在栈内存中都没有默认初始化值,必须手动初始化后才可以参与运算。 7、匿名对象: 即没有名字的对象,简化书写用的。基本使用: 1、当对对象的方法只调用一次时,可以用匿名对象来完成 这样写比较简化,如果对一个对象进行这个成员的调用,必须给这个对象起个名字 2、可以将匿名对象作为实际参数进行传递。一旦对对对进行多个成员操作时。必须要对对象起个名字。 Eg: Main(){ Show(new Car())} Public static void show(Car c) { C.num=3; C.color=”back";C.run();} 8、面向对象三个特征: 封装: 是指隐藏对象的属性和实现细节,仅对外提供公共访问方式,凡是面向对象必须有封装性。 特点: 将变化隔离 便于使用 提高复用性 提高安全性 原则: 1、将不需要对外提供的内容都隐藏起来。 2、把属性都隐藏,提供公共方法对其访问。在代码中的体现: 1、将成员变量都私有化,并通过共有的方法对其进行访问,这两个方法是:setXxxgetXxx 2、只要不准备对外提供的全部都封装起来,3、私有仅仅是封装的一种表现形式,函数是最小的封装体。方法需要私有吗? Public static void selectSort(){ Swap();} Private void swap()//此处私有是因为位置置换不用提供给用户。{ } 代码实现: Class Person { Private int age;//为了不让其他程序直接访问age属性,避免错误的数据,可以使用一个关键字来完成private私有,它是一个权限修饰符。 Public void setAge()//对外提供函数是可以控制你输入的参数。//一个成员变量通常对应的两个方法、{ If(a>130||a<0){ Age=a; Speak();} Else System.out.println();} Public void getAge(){ Return age;} Void speak(){ Sop();} } Class PersonDemo { Public static void main(String[] args){ Person p=new Person();P.age=-20;//错误数据是因为对象直接访问age属性造成的。P.speak();} } 总结:之所以对外提供访问方式,就是因为可以在访问方式中加入逻辑判断等语句 对访问的数据进行操作,提高代码的健壮性。凡是set开头的返回值类型是void,get开头的跟它的返回值类型一致。 Day01总结: 1、计算机常识:包括了软件的简单划分:系统软件 windos等和应用软件 QQ、迅雷等 2、人机交互方式:图形化界面GUI、命令行方式CLI: 3、常用的命令:cd:进入目标路径、cd..退出当前路径、mk:创建文件、rd:删除文件,dir:列出当前目录、cls:清屏、exit:退出dos窗口 cd回到根目录 rds删除根目录下所有的文件(这里是比较牛的地方,因为windos都是从里到外的删除,在dos命令下必须首先删除里面的文件保证没有任何文件下才能删除当前的文件目录)*:代表通配符、notepad:记事本; 4、Help/?为dos中寻找帮助的工具,可以帮助列出所有的dos命令 5、Java的三种技术架构:javaSE:标准版:是为了开发桌面和商务应用程序提供的解决方案 javaEE:企业版:为了开发企业环境下的应用程序而提供的一套解决方案;javaME:小型版:是为了开发电子消费品和嵌入式设备提供的解决方案; 6、Java的简单特性:跨平台性(平台在此所指的是操作系统,而操作系统指的是平台)怎么做到跨平台?因为有jVM的出现,只要计算机上安装上虚拟机就可以运行不同的程序 jVM作用:能解释java语言的程序; 正是因为有了JVM才使java语言具备了良好的移植性; 7、java语言的开发环境: JRE:java Runtime Enviroment Java运行环境:包括javaJVM和核心类库 简单:JRE=JVM+核心类库 JDK:java Development kit java 开发工具:包括java工具包 比如:javac 编译器 java 运行 总的说来就是一句话:使用JDK开发完的程序交给JRE运行; 8、下载JDk和安装JDK 详细见:下载JDK和安装JDK专题 下午: 1、环境变量的配置: 三个步骤:下载安装、配置环境变量、javac编译运行(如果dos窗口显示出javaJVM中所有的参数信息代表已经配置成功) 2、path环境变量有什么作用?用于记录应用程序所在的路径; 3、配置Path环境变量目的:为了方便任何情况下都能执行应用程序 4、区别:不用找路径了,windos找路径 5、临时配置环境变量:Set path: 6、在原有的基础上添加新的参数值:set path=E:javaJDKjdk1.7_0_3bin%path%:注意后面的部分(注意:配置时要尽量配置在前端,否则JDK会优先运行其他程序) 7、Java程序: Class Demo { Public static void main(String[] args){ System.out.println(“HelloWorld!”);} } 从上面的程序中可得: 1、java文件的扩展名为:.java 2、javac 对该java文件进行编译; 3、java对生成的class文件进行运行; 类就是存储代码的地方; 关键字:class 类名的书写规范:英文和数字的组合,英文单词第一个字母大写 如果有几个组成,每个英文字母的首字母大写(回忆变量名书写规范----已经忘记了) ------自己写好的文件称之为源代码或者源文件,必须翻译成计算机能识别的文件 NoSuchMethodError:main ;没有main方法(缺少主函数) 回忆最常见的几个异常(已经忘记,java面试中这么一道题:说出你经常遇到的异常,至少五个)----------------public static void main(String[] args)main函数可以保证该类独立运行; 它是程序的入口; 它会被JVM所调用; argments:args;参数 作用:可以让一个类可以独立运行; java程序的主函数,程序的开始;执行的起始点; 面试题:一个java程序中是否只能有一个main函数?(自己查找--已经忘记)可以重载main()函数(重载和覆盖知识点已经忘记,晚上补齐)补习: 重载:什么是重载:Overload表示同一个类中可以有多个名称相同的方法,重载的特点:参数列表的方法各不相同(参数个数和参数列表) 为什么用重载:是静态多态性,即同名不同参,好比一个人可以用不同的餐具一样; 重写:override覆盖一个方法,并且对其重写,以求达到不同的作用,-------------System.out.println("");println与print的区别:前者换行也就是回车,后者没有回车; 作用:显示效果不一样; java的输出语句:输出在控制台上; java对应的程序就是java虚拟机 弄清楚编译时期和运行时期出现的机制和错误:(后期的异常机制中涉及到)------------初学者在初学的时候遇到的问题: 1、文件名保存错误; 2、目录不对 eg:只进入了盘符,没有进入文件中; 3、扩展名保存不对;eg:123.java.txt扩展名隐藏; 解决方法,用dir查看文件详细信息,显示其扩展名; 4、主函数找不到; 5、编译失败; 8、classpath:类文件路径 set classpath=c:myclass 将java的类文件告诉系统,java虚拟机在执行时就会制定的目录下查找; 作用:简单一句话:告诉java虚拟机要运行类文件的位置; 没告诉位置就在当前文件下找,告诉位置就去告诉位置查找! set classpath=c:mycalss;多了一个分号,表示告诉虚拟机按照所指定的目录下查找的java程序,如果没找到会在当前目录下再次查找; 一般情况下不加分号;如果加分号和自己指定的意愿有悖; set calsspath=.;c:myclass表示当前路径和指定的目录; 9、path与classpath的区别? path是用于定义系统中的可执行程序的所在路径。方便于执行系统中的执行文件,比如 exe bat。 classpath用于定义java的类文件class文件的所在路径。是为了让jvm去classpath路径下查找要运行的java程序。 10、明明看到类名,但是运行时找不到类文件,只有两种情况: 1、类名写错,只要源文件和类名相同可以避免此错误; 2、设置了classpath路径制定了查找路径 Day09总结: 上午: 1、final关键字: Eg:代码实现: Class Fu { Final void method(){ //code...访问低层代码 } } Class Zi extends Fu { Void method() { Sop(“haha”);} } 以上代码体现出继承的弊端,因为父类的method的方法访问了系统的低层代码。当子类对其覆写,就不会去访问父类的meth的方法,直接用自己的method这样就出现了代码的不严谨性,所以此时需要用final关键字进行修饰。注意为什么不把类加final修饰,因为可能该类中会出现很多功能。有些是不需要被覆写的。有些是被调用的。所以只能根据自己所需对相应的成员进行修饰。 2、Final的特点: 1、final是一个修饰符,可以修饰类、方法、变量(成员变量、局部变量) 2、Final修饰的类不可以被继承。 3、Final修饰的方法不可以被覆盖。 4、Final修饰的变量是一个常量,只能被赋值一次。是为了增强阅读性,只要数据是固定的,就将这个数据用一个名称来表示,并用final修饰。常量名称都是大写字母,多个单词组成时用下划线来分隔。 代码体现: Eg: Class Zi { Static final int num=90;//必须对变量进行初始化,不知道要最终化哪个值,所以必须对它进行初始化。加静态也是一样的,同样的道理,并且被初始化,此时静态和final没有必然的联系。当变量被final修饰时,说明变量已经是一个常量值,此时不能被修饰,可以用static来修饰。 Public stati double PI=3.14;Void method(){ Final int x=4; X=8; Sop(num);//既然是在操作一个固定的值。为什么不把4直接写在此处,如果这样做的的话,阅读性极差,你根本就不知道它所代表什么?为了增强阅读性,此时数据是不变化的,所以我们需要给它起个名字,并且用final来修饰。这样的话它也是固定的不变的。 注意:被final修饰的数值只能被覆写一次,并且修饰的常量名全部大写,多个单词组成时用下划线进行分隔。Eg:final int PERSON_AGE=4;} } 3、抽象类: 特点: 1、没有方法体的方法,称为抽象方法,必须存放在抽象方法类中,抽象方法和抽象类必须用abstract关键字来修饰,2、抽象类不可以被实例化,为什么?因为调用抽象方法没有意义?为什么?因为它连方法体都不存在? 3、抽象类必须由其子类将抽象类中的抽象方法都覆盖后,其子类才可以被实例化,否则该子类还是抽象类。Eg: Abstract class Demo { Abstract void show();} Class SubDemo extends Demo Void show(){} //此时把父类中抽象方法覆盖,此时才能被实例化。} 比如水果,它就是抽象的,不具体它包含各种各样的水果,每种水果有它自己的体现。 抽象类涉及的问题? 1、抽象类中是否可以定义非抽象的方法? 可以 首先抽象类是一个类,类是用来描述事物,只不过描述事物过程中有些信息不具体,抽象类和一般类异同点: 相同:抽象类和一般类都用于描述事物,都可以定义成员。不同:抽象类中可以定义抽象成员函数,(抽象要么修饰类要么修饰函数)而一般类不可以。 抽象类不可以实例化,一般类可以实例化。 2、抽象类中是否有构造函数? 有,而且抽象类虽然自身不可以被实例化,但是其子类覆盖了所有的抽象方法后,是可以实例化的。所以抽象类的构造函数是用于给其子类对象进行实例化。 3、抽象类通常都是一个父类? 是、因为需要子类去覆盖父类中的抽象方法。代码体现: Abstract class Demo{ Abstract voif show1();Abstract void show2();} Abstract class SubDemo extends Demo { Void show1();} Class Test extends SubDmeo { Void show2();} 4、抽象类中可不可以不定义抽象方法? 可以;看上去没有什么意义,其实有点意义,就是不让这个类创建对象,为什么不让创建? 代码体现: interface InterTest//这是一个测试接口,有4种测试方式。 { void test1();void test2();void test3();void test4(); } abstract class InterTestImpl implements InterTest//用这个类进行所有的空实现。但是创建对象是毫无意义的。所以用抽象。 { public void test1(){} public void test2(){} public void test3(){} public void test4(){} } class Test2 extends InterTestImpl { public void test2(){} } class Test3 extends InterTestImpl { public void test3(){} } /* class InterTestImpl implements InterTest { public void test2()// { sop(“testimpl test2”); } public void test1(){}//这样做实现太麻烦。代码重复。如何改进? public void test3(){} public void test4(){} } */ 5、抽象关键字 不可以和那些关键字共存? Final:修饰了类是一个最终类,不可以被继承,然后abstract修饰的类必须是父类,需要被继承、冲突、非法的修饰符组合,abstract 和final Static:抽象方法被static修饰,就具备了可以被类名直接调用的的特点,但是抽象方法被调用没有意思。 Priavte:因为抽象方法被私有,无法被覆盖。 代码体现: 雇员实例: 需求:公司中程序员有姓名、工号、薪水、工作内容。 项目经理除了姓名、工号、薪水、还有奖金、工作内容 进行数据建模 做问题领域的分析就是找出问题领域的对象。 分析: 在这个问题领域中有两个对象: 程序员: 属性:姓名,工号,薪水 行为:工作内容 项目经理: 属性:姓名、工号、薪水、奖金 行为:工作内容。 这时候不能用项目经理去继承程序员。因为职能不同,但是有共性,只能抽取。 就有了员工: 属性:姓名,工号,薪水 行为:工作内容 */ abstract class Employee { private String name;private String id;private double pay;Employee(String name,String id,double pay){ this.name=name; this.id=id; this.pay=pay;} public abstract void work();//工作内容是无法知道的。} class Programmer extends Employee { Programmer(String name,String id,double pay){ super(name,id,pay);} public void work(){ System.out.println(“code”);} } class Manager extends Employee { private double bonus;Manager(String name,String id,double pay){ super(name,id,pay); this.bonus=bonus;} public void work(){ System.out.println(“manage”);} } 4、接口: 格式:interface{} 表现特点: 1、里面的方法都是抽象的。 2、接口中的成员都有固定的修饰符,最常见的成员:全局常量抽象方法。只是最常见,不代表只有它们没有其他的,全局常量,共有的不需要对象,直接用接口调用的,不可变的。 表现形式:Public static final 抽象方法:public abstract 3、接口的成员都是public的。 4、接口是不可以创建对象的。就相当于是抽象的特殊表达形式。(但是有区别和抽象类) 5、类与类之间是继承关系,类与接口之间是实现关系。 6、接口的出现可以多实现,避免了单继承的局限性。 7、一个类在继承一个类的同时,还可以实现多个接口、8、接口与接口之间是继承关系,而且可以多继承,以为接口的方法都没有主体。思想特点: 1、对外暴露的规则。 外设要介入计算机中,因为计算机外面提供了接口,这就是规则。 2、程序的功能扩展 3、降低了耦合性 4、用来多实现 结合电脑主板的思想进行阐述,它是个规则。对外提供的规则 它提高了我们功能的扩展性,降低了耦合性。主板和声卡:主板使用规则,声卡实现规则。 与抽象类的区别:抽象类有单继承的局限性,接口没有 5、java对多继承记住改良,以多现实接口的方式来体现。差别:多继承因为父类中有相功能时,会造成不确定性。为什么可以实现多实现? 因为继承中父类的方法有方法体?这才是造成不确定性的根本原因,而此处是没有方法体的。 代码体现: interface A { //int show();//这样是不可以的。无法覆盖。 void show();} interface B { // void method(); void show();//当有重复的方法时。但是此时子类复写它是可以的,为什么? //因为继承中父类的方法有方法体。这才是造成不确定性的根本原 因。而 //此处是没有方法体的。 } class C extends D implements A,B//多实现。此时c必须覆盖两个方法 { public void show(){} //public void method(){} } //一个类在继承一个的类的时候还可实现多实现 class D { public void function();} //接口之间是可以继承,而且支持多继承。 interface InterA { void showA();} interface InterB { void showB();} interface InterC extends InterA,InterB//为什么此处可以实现多继承,因为方法没有主体。 { void showC();} class InterfaceDemo2 { public static void main(String[] args) { C c=new C(); c.show(); System.out.println(“Hello World!”); } } 6、抽象类和接口之间的区别: 共性:它们都是不断抽取出来的抽象非概念 区别: 1、抽象类只能被单继承、接口可以被多实现,避免了单继承的局限性。 2、抽象类中可以定义抽象方法,和非抽象方法,它可以用于定义体系的基本共性的内容。接口中只能定义抽象方法,它主要用于对象的功能的扩展。 3、抽象类是继承关系,是is a关系,接口是实现关系是like a关系。 4、抽象类中的成员修饰符都是自定义的,接口中的修饰符都是固定的。记住:不要把接口狭义的理解为interface,应该理解广义些,就是对外提供的规则,凡是对外暴露的都可以是接口。 实现代码: 1、abstract class 犬 { public abstract void 吃饭(); public abstract void 吼叫(); } interface 搜爆 { public void 搜爆(); } class 搜爆犬 extends 犬 implements 搜爆//这是即具备了犬的基本特性,又具备了搜爆功能。 { public void 搜爆(){} public void 吃饭(){} public void 吼叫(){} } class 搜爆猫 extends 猫 implements 搜爆 { public void 搜爆(){} } 记住: 类里面都是定义的一些基础内容,接口里面都是定义一些特性内容,这样的方便了对其进行扩展。 //抽烟的学生,抽烟是额外功能。 2、abstract class Student { abstract void study(); } interface Smoking { void smoke(); } class SomkeStudent extends Student implements Smoking { public void study(){} public void smoke(){} } //烟民。学生烟民 问题领域不同,对象的属性和行为也不同。 abstract class Somker { abstract void smoke(); } interface Study { void study(); } class StudentSmoker extends Smoker implements Study { public void smoke(){} public void study(){} } 7、多态:重点掌握 定义:某一类事物的多种存在形态。代码实现: class 动物 {} class 猫 extends 动物 { } 猫 x=new 猫(); 动物 y=new 猫();//父类的引用变量指向了其子类的对象。 多态在代码中的体现,父类或者接口的引用指向了自己的子类对象。 实现代码: class Animal { abstract void eat(); } class Dog extends Animal { void eat(){ sop(“啃骨头”);} void lookHome() { sop(“看家”);} } class Cat extends Animal { void eat(){ sop(“吃鱼”);} void catchMouse(){ sop(“抓老鼠”);} } class Pig extends Animal { void eat(){ sop(“猪饲料”);} void gongdi(){ sop(“拱地”);} } class DuoTaiDemo { public static void main(String[] args){ //Cat c=new Cat(); //c.eat(); //Cat c1=new Cat(); //c1.eat(); //method(c); //method(c1); 重要知识点:----开发都用! Animal a=new Cat();//此处猫对象类型自动向上提升---向上转型,当指向使用体系基本功能时,可以向上转型操作。 为什么体现多态性? 首先猫是一个实体,是一个猫类型,因为有了继承,是动物中的一种,把这个实体称之为动物也可以,所以它具备了两种形态,猫和动物。这便是体现了多态性。 //一旦向上转型,猫就不是猫了,已经是动物类型了。 a.catchMouse();//编译失败。 但是现在想执行猫的抓老鼠的功能怎么办? 向下转型: Cat c=(Cat)a;//向下转型。当使用子类对象中的特有内容时,才做向下转型。 c.eat(); c.catchMouse();//此时是可以实现猫的抓老鼠的功能的。 总结:在多态转型中,至始至终只有子类对象做着类型的变化。 method(new Cat()); } public static void method(Animal a)//Animal a=new Cat();{ 重点知识点:instanceof if(a instanceof Cat)//对象instanceof 类型 判断具体对象是否是指定的类型。 { Cat c=(Cat)a;//编译通过,但是不能运行,此时类型转换异常classCastException; //此时为了程序的严谨性,需要对传入的的对象进行判断。 c.catchMouse(); } else if(a instanceof Dog) { Dog d=(Dog)a; d.lookHome(); } a.eat(); 总结: instanceof是一个关键字,用于判断对象的类型。什么时候用? 当进行向下转型时,先判断该对象是否符合被转成的子类型。 } } 8、重点理解: 1、多态的好处:提高了代码的扩展性,有了多态,前期设计好的内容可以使用后期出现的子类内容,对于指挥对象做事情这件事情,如果对象很多,指挥起来很麻烦,抽取对象的共性类型,对该类型的事物进行指挥就会变的很简单。 2、多态的前提: 1、必须要有关系:继承、实现。 2、必须有覆盖的操作。 3、多态的弊端:前期的程序虽然可以使用后期出现的子类内容,但是只能使用子类覆盖父类中的内容,不能使用子类中的特有内容。第三篇:黑马程序员java培训就业班笔记:day06总结
第四篇:黑马程序员java培训就业班笔记:day01总结
第五篇:黑马程序员java培训就业班笔记:day09总结