疑点6对象初始化和调用成员
综述,这篇笔记中记录的是复习毕向东毕老师java基础教程视屏中的知识点,
视屏包括(共44个):第5天(12个),第六天(10个),第七天(15个),第八天的01~07(7个)
涉及到的知识点有:1类以及类成员,2封装private ,3构造函数和构造代码块,4this关键字,5静态static,6对象初始化和调用成员7继承和聚集关系8final关键字9抽象类10接口11多态
通过视屏学到了面向对象结构(6个点:1类,2构造代码块,3构造函数,4类成员,5对象,6对象调用成员)以及一些关键字(4个:this,private,static,final)
了解到两种设计模式:单例设计模式,模版方法模式。
思想:名词提炼法,继承的使用思想查阅父类功能,创建子类对像。String的一个使用思想查表法
学到的单词encapsulation封装
总结一下,面向对象的特点有:封装、继承、多态
在这一阶段要会写的代码:1冒泡排序(第二次循环的写法要注意(int x =0 ; x 笔记内容 理解面向对象的概念, 面向对象将功能进行了封装,强调具备了功能的对象。面向过程强调的是功能行为。 1类以及类成员 我们在开发中,可以尝试通过名词提炼法得到对象与对象的关系。比老师在视屏中说开发是找对象,建立对象,使用对象并维护对象之间的关系的一种工作 那么类就是对现实生活中事物的描述,对象是实实在在的个体,我们可以在java中通过new关键字在堆内存中创建对象。比如说,人类是一个类,他描述了人类的特征,而我就是人类的对象。我具有人类的所描述的特征。在java类中人类可以是这样的——他具有一些特征,比如人类的外形(四肢,头发,五官等等),而具体到我们个体就是对象了。 成员变量和局部变量作用范围不一样,(对于作用域,在自己写代码时,也常常遇到不清楚作用域的一些关键字,如return等,以后要进行总结) 成员变量和局部变量在内存中的位置也不一样。成员变量在堆内存中,因为对象的存在而在内存中存在,局部变量存在在栈内存中。 关于主函数的几个要点。1一个java文件中,可以在多个类中写主函数。2我们还可在本类中建立本类对象。所以我们想在主函数中调用主函数,就有了两种方式,第一就是将这个方法设为静态的,当这个方法不能是静态的时候,当然或者这个方法是非静态更好些时,我们可以使用第二种方法,第二中方法是:在主函数中建立本类对象,然后使用对象调用这个非静态的方法。写个例子吧 class car{ String color; int num; void run( ) { System.out.println(color+”…..”+num); } //你看,run方法不是静态的,但我可以这样调用它 public static void main( String[] args){ Car c = new Car( ); c.num = 10 ; } } 匿名对象的应用有两种,一种是当对象只调用一次方法时(当对象需要多次调用方法时,必须给对象命名),可以简化代码;另一种是,我们可以将匿名对象作为参数传递。 class{ public static void main(String[] args){ show(new Car( )); } public static void show(Car c){ c.num = 6 ; c.color = “yellow” ; } } 这段代码需要知道的一点是,我们在主函数中调用了show方法,并传入了一个匿名对象,但这个匿名对象,是有名字的,它的名字是c 。 2封装private 封装的英文单词是encapsulation。 封装就是隐藏对象的属性和实现细节,仅对外提供公共访问方式。 封装的好处有4点:1将变化隔离,2便于使用,3提高重用性,4提高安全性 封装的原则:把不需要对外提供的属性等都隐藏起来,我们只需要对外提供公共方法就可以了。在提供给外界的访问方法中,可以加入逻辑判断等语句,对访问的数据进行操作。这样提高了代码的健壮性。 封装不是私有,私有是封装的一种体现形式。 3构造函数和构造代码块 构造函数有3个特点,函数名和类名一致,而且没有返回类型,对象一建立就会调用与之对应的构造函数,只调用一次 而且构造函数是可以私有化的。当一个类没有构造函数时,系统会添加一个默认的空参数的构造函数,如果自己定义了构造函数,系统就不再添加 构造代码块优先于构造函数执行,定义的是不同对象共性的初始化内容。构造函数和构造代码块的区别:构造函数是给对应的对象初始化,而构造代码块是给所有的对象初始化。比如说有一个类,有两个构造函数,而参数不同,只有在建立对应的对象时被调用,而构造代码块只要是用这个类建立对象都会执行。 4this关键字 局部变量可以给局部变量赋值,诸如name = name是可以的 this关键字的两种用法 构造函数中的this。 1在构造函数中我们常常要把参数的值赋给成员变量的name,而不是局部变量中的 name,这时就要这样写,this.name = name ;这时 this 标识了name的所属是成员变量。 2this可以用于构造函数间的互相调用,如this(name),表示调用了参数为name的构造函数。需要注意的是死循环的情况,还有用this语句只能写在构造方法的第一个语句位置 另外一般函数是不能调用构造函数的,因为this()这种写法不能用在一般函数中。 class Person{ private String name; private int age ; Person(){} Person(String name){ this.name = name ; } Person(String name,int age){ this(name) //——>相当于Person(name);但遗憾的是在构造函数中不支持这种写法 this.name = name ; this.age = age ; } } 方法中的this this代表它所在函数所属对象的引用。比老师说的是那个对象在调用this所在的函数,this就代表哪个对象。 当定义类中功能时,该函数内部要用到调用该函数的对象时,这时用this。但凡本类功能内部使用了本类对象,都用this表示。(this是一个变量,对象调用有this的方法的时候,就把自己的地址值赋给了this) ex: class Person{ private String name ; private int age ; Person( String name,int age){ this.name= name ; this.age= age ; } public boolean compare( Personp){ return this.age == p.age; } } 5静态static, static关键字。static用于修饰成员(成员变量和成员函数)。当成员被静态修饰后,就多了一个调用方式,除了可以被对象调用外,还可以直接被类名调用。 static在内存中的特点: 1随着类的加载而加载。随着类的消失而消失。说明它的生命周期长。而像未被static修饰的成员变量,没有对象是不会被加载的。有了static修饰,只要类加载了,在内存中就存在了。 2优先于对象存在。对象是后存在的。 3被所有对象所共享, 4可以直接被类名调用。 实例变量和类变量的区别有两点:1存放位置。实例变量存在于堆内存中,类变量存在于方法区中。2生命周期。类变量生命周期最长,类消失才会消失。而实例变量随对象的消失而消失。 静态使用要注意:1静态方法不能访问非静态成员。因为静态方法存在的时候,非静态的成员还没有存在。2静态中不能定义this,super关键字。因为静态优先于对象存在,所以静态方法中不可以出现this。 静态的好处和弊端 主函数: 1是一个特殊的函数,做为程序的入口,可以被jvm调用。 2访问权限是最大的。 3没有返回值。 4main不是关键字,是一个可以jvm识别的特殊单词。 5有参数,参数是一个字符串类型的数组。jvm在调用主函数时,传入的是new String[0].我们也可以给主函数传值。在dos中格式是:java 类名 haha hehe heihei 。 6主函数是固定格式的。 什么时候使用静态 我们什么时候定义静态变量呢?当对象中的属性具有共享数据时(是共享数据而不是共享属性)。对象中特有的数据要定义成非静态。 什么时候定义静态函数呢?当功能内没有访问到非静态数据(非静态的属性)。该功能可以定义成静态的。 静态的引用——工具类。 我们写了一个ArrayTools。虽然可以通过建立对象使用类找给中的方法。不过,对象是用来封装数据的,可是ArrayTools对象昂并未封装特有数据,操作数组的每一个方法都没有用到ArrayTools对象中的特有数据。这时就考虑到为了让程序更严谨,是不需要对象的。所以可以让ArrayTools中的方法都定义成static的。直接通过类名调用即可。为了更为严谨,可以将对象的构造函数私有化,让其不可以创建对象。 静态代码块。静态代码块的格式static{ }。特点:随类的加载而执行,只执行一次。作用是对类进行初始化。 有几个点要注意1String st = null;这是类是没有加载的。因为没有用到类中的内容。2通过new创建对象时,就已经使用到了类中的内容,,被用到的内容必然有构造函数。3静态代码块,非静态代码块,构造函数的执行顺序依次是:静态代码块——>非静态代码块——>构造函数。它们分别给类,对象,对应对象进行了初始化, 6对象初始化和调用成员 7继承和聚集关系 继承的意义:1提高代码的复用性2让类与类之间产生了关系。有了这个关系,才有了多态的特性。 需要注意的是,千万不要为了获取其他类的功能,简化代码而去继承。必须是类与类之间有所属关系才可以继承。所属关系is a。 java语言中,只支持单继承,不支持多继承。因为多继承容易带来安全隐患,当多个父类中定义了相同功能,当功能内容不同时不确定要运行哪一个。但是java保留这种机制。并用另一种体现形式来完成表示,就是多实现。 java支持多层继承,也就是一个继承体系。 使用思想:查阅父类功能,创建子类对像。 聚集关系has a 。分聚合和组合。聚合例如球员和球队,组合例如手和人。 子父类中成员的特点。类中成员主要有变量,函数,构造函数。对于变量来说,继承时如果子类中出现非私有的同名成员变量时,子类要访问本类中的变量,用this,子类要访问父类中的同名变量,用supper。supper的使用和this的使用几乎一致,this代表的是本类对象的引用,supper代表的是父类对象的引用。 对于函数,会发生覆盖 这一章要了解String、StringBuffer和StringBuilder的常见用法,和区别。 新的名池:常量池。内存中有常量池,常量池中有一个数组,用于存储常量。方法区(共享区)中有方法区,静态区,还有常量池。方法调用链。 CURD C:create U:update R:read D:delete 类String 4个点:1s是一个类类型变量,“abc”是一个对象。2一旦被初始化就不可以被改变3s和s1的区别。4复写了Object中的equals方法。 类String是 包java.lang中的类,被final修饰,不能创建子类,方法不能被复写。类String有很多中的构造函数。 String s = newString() ; 这种写法是不多见的。但也有需要使用这种写法的特定情景。大多使用的是这种情况:String s = “abc”。 String s = new String() ;这种写法和String s1 = “abc” ;是有区别的。s代表一个对象,s1代表两个对象。 类String的特点。1字符串最大的特点是,一旦被初始化就不可以被改变。如String s1 = “abc” ; s1 = “kk” ; 字符串对象“abc”,并没有变过,它依然存在内存中。变的是s1的指向,s1的指向由”abc”,变为了”kk” 。2类String 复写了 类Object 中的equals方法。 类String的方法 对字符串的常见操作有获取和判断。 1获取的方法。 1.1、length():获取字符串长度 1.2、charAt(int index):获取指定位置上的某个字符。 1.3、indexOf(int ch):根据字符获取该字符在字符串中的位置。 indexOf(int ch,int fromIndex):获取从指定位置开始,该字符在字符串中的位置。 indexOf(String str):获取从指定位置开始,该字符串在字符串中的位置。 indexOf(String str , int fromIndex):获取从指定位置开始,该字符串在字符串中的位置。当要查找的字符或字符串不存在时,返回-1。 Mark 13 02 StringBuffer StringBuffer是字符串缓冲区,是一个容器,被final修饰。线程安全,即线程同步。具备对字符串进行存储,删除,获取,修改的功能。 方法 使用append(……)方法可以往StringBuffer对象中添加数据。但不支持添加byte,short类型的数据(可以将其提升为int型)。 append()添加到结尾。 intsert(……)插入 StringBuilder和StringBuffer类似,不同的是StringBuilder是线程不同步的,用于单线程,效率高。StringBuilder出现于JDK1.5。 正则表达式的特点 正则表达式是符合一定规则的表达式。用一些特定的符号来表示一些代码操作,专门用于操作字符串。正则表达式的弊端:正则越长,阅读性越差。可以简化对字符串的复杂操作。先举出了一个例子:对QQ号码进行校验。对qq号码的要求是5~15位,0不能开头,只能是数字。原始的方法有两种:if判断和Integer的parseInt()静态方法判断是不是数字。 我们可以使用类String的方法将String对象按照正则表达式匹配,切割,替换,获取 匹配使用String类的match(Stringregex)方法,返回的是boolean。 [abc] a、b 或 c(简单类)判断字符串某个位置出现的字符。 “[abc]” 表示操作对错如果有一个字符,而且这个字符是a、b或c,返回true [] \d * ? \w …… 切割使用String类的split(Stringregex)方法。1按一个或多个空格切的正则表达式是(“ +”),2“。”表示按任意字符切,“\\。”表示按。切,3按减斜线切“\\\\”,4按重复一次或多次切“(。)\\1+”。当要对一个结果重用时,用()将其封装成一个组。返回的是规则以外的字符串。 替换 获取,简单获取字符串的子串,可以使用类String 的方法 要学会 用类System 的方法得到系统属性,并动态加载一些属性信息。 用 Runtime类中的exec()方法打开程序,打开文件。Math类中的方法。生成随机数的两种方式 思想:名词提炼法,继承的使用思想查阅父类功能,创建子类对像。String的一个使用思想查表法。 单词类format:格式化。 类System 类System 是 包java.lang中的类。它的构造函数是私有的,不能被实例化,也因此它的所有方法都是静态的 System有两个重要的字段。一个是out,指的是标准输出,默认的是控制台。一个是in,标准输出,默认是键盘。 下面列举一些类System中常用的方法。 可用于获取系统属性的方法是方法getProperties(), 返回的是 类Properties。Porperties是 类HashTable import java.util.Properties; public class System_getProperties { public static void main( String[ ] args){ //得到的是一个成对的集合 Properties pro =System.getProperties(); //取出 for(Object key :pro.keySet() ){ Object value =pro.get(key) ; System.out.println (key+": "+value); } } } 在jvm启动时动态加载一些属性信息。要在运行java时加上-D属性名=属性值类型。 类Runtime 类Runtime 是java.lang中的类,使用了单例涉及模式,应用程序不能创建自己的Runtime对象,保证了对象的唯一性。但这个类并不是没有创建对象,而是应用程序一执行,这个应用程序的Rumtime对象就已经自动创建完毕了。我们可以通过静态方法getRuntime() 得到程序运行时的 Runtime 对象。 得到程序的运行时的Runtime对象后我们可以使用 类Runtime 的方法。下面是类Runtime的一些方法。 方法exec(String command),( exce是 单词execute 的缩写)。返回类型是Process。作用是打开另一个应用程序。例如 public class RuntimeTest { public static void main(String[] args)throws Exception{ Runtime r = Runtime.getRuntime(); Process p = r.exec("C:\\WINDOWS\\system32\\winmine.exe"); //要抛出IOException Thread.sleep(1000); //杀掉自己创建的子程序。 p.destroy(); //打开文件,要先找到与之相关联的程序 r.exec("notepad.exe c:\\text.txt"); } } 类Date 类Date 是包java.util中的类 。对时间进行了描述。 类Date 中的大部分构造方法都已经过时。Date() ,Date(long date)是未过时的。 import java.util.*; class DateTest { public static void main(String[]args){ Date d = new Date(); System.out.println(d); } } //打印结果是:Mon Aug 19 16:50:31 CST 2013。当然,这是我现在的时间。 下面来看一下与Date相关的 类DateFormat。 类DateFormat,是 包java.text 中 类Format 的子类 。它的唯一的构造方法DateFormat()被protected修饰,不能创建对象。但DateFormat有一个子类 类SimpleDateFormat。我们可以使用这个子类创建对象,并调用父类 类DateFormat的方法。 importjava.text.SimpleDateFormat; import java.util.Date; class DateTest { public static void main(String[]args){ Date d = new Date(); System.out.println(d); //对日期格式化 //将模式封装到SimpleDateFormat对象中 DateFormat df = new SimpleDateFormat("y年M月d日 h:m:s"); //调用format方法让模式格式化指定Date对象。 String time =df.format(d); System.out.println(time); } } 类Calendar 类Calendar 是 包java.util 中的类。是抽象的。类GregorianCalendar 是 类Calendar 的子类。我们可以使用GregorianCalendar创建对象,调用 父类Calendar 的方法和字段。要注意的一点是,Calendar中的字段都是从0开始的。 Calendar中比较重要的方法get()和set() importjava.util.Calendar; importjava.util.GregorianCalendar; public class CalendarTest { public static void main (String[]args){ Calendar c = newGregorianCalendar(); sop(c); /* 以下为打印结果 * java.util.GregorianCalendar *[time=1376905999000,areFieldsSet=true,areAllFieldsSet=true,lenient=true, *zone=sun.util.calendar.ZoneInfo[id="Asia /Shanghai", * offset=28800000,dstSavings=0, * useDaylight=false,transitions=19,lastRule=null], *firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1, * YEAR=2013,MONTH=7,WEEK_OF_YEAR=34, *WEEK_OF_MONTH=4,DAY_OF_MONTH=19,DAY_OF_YEAR=231, *DAY_OF_WEEK=2,DAY_OF_WEEK_IN_MONTH=3,AM_PM=1, * HOUR=5,HOUR_OF_DAY=17,MINUTE=53,SECOND=19, *MILLISECOND=0,ZONE_OFFSET=28800000,DST_OFFSET=0] */ sop(c.get(Calendar.YEAR)+"年" +c.get(Calendar.MONTH)+"月" +c.get(Calendar.DAY_OF_MONTH)+"日"); //下面我们用查表法来自定义月份的格式 String[] mons= {"一月","二月","三月", "四月","五月","六月", "七月","八月","九月", "十月","十一月","十二月" }; int index =c.get(Calendar.MONTH); sop(mons[index]); } public static void sop(Object obj){ System.out.println(obj); } } 类Math 类Math是包java.lang 中的类,是一个工具类,Math中的方法都是静态的。包util中有一个类Random,可以实现相同的功能。new java.util.Random 方法ceil(double d)返回大于指定整数的最小整数 方法floor(double d)返回小于指定整数的最大整数 方法round(double d)返回四舍五入的结果 方法pow(double a,double b) a是底数,b是幂 方法random()很重要。得到0~1之间的小数,包含0,不包含1。是伪随机。它是通过底层的算法得到的,有了算法,使用很多次,就可以得到其中的规律。所以说是伪随机。 int i =(int)(Math.random()*10+1) ; //两种生成随机数的方式 public class MathTest { public static void main(String[]args){ for(int i = 0; i<10;i++){ double d = Math.random(); SOP.sop("Math中的方法生成的随机数:"+d); } //用java.util包中的Random类生成随机数 java.util.Randomr = new java.util.Random(); for(int x = 0; x<10;x++){ SOP.sop(r.nextInt(10)); } } }String、StringBuffer和StringBuilder
正则表达式
replaceAll
(String regex,String replacement)
。将重叠的字符替换成单个字符(“(。)\\1+”,“$1” ),$表示获取组中的字符。返回的是新字符串。
substring
(int beginIndex)
substring
(int beginIndex, int endIndex)
。用正则表达式可以实现较复杂的获取。
步骤是1将正则表达式封装成对象,2让正则对象和要操作的字符串相关联。3关联后,获取正则匹配引擎,4通过引擎对符合规则的子串进行操作,比如取出。
关于正则表达式,在api中有描述。包
java.util.regex中
类 Pattern 可以对正则表达式进行封装。类 Pattern没有对外的构造函数,不可以创建对象。方法compile(String regex)和方法
compile
(String regex, int flags)
是静态的,返回类型是本类对象。matcher(CharSequence input),返回类型是类Matcher 类型。
类Matcher中有 方法matches(),返回boolean ;
方法group(),返回的是获取匹配后的结果,要先使用 方法find() 进行匹配。功能类似于迭代器。在正则表达式中有边界匹配器。\b是单词边界匹配器,例如”\\b[a-z]{4}\\b”是一个规定一个单词由4个小写字母组成 ,的正则表达式。需要注意的是同一个匹配器用的是同一个索引位
邮箱匹配
相对精确的匹配”[a-zA-Z0-9_]+@[a-zA-Z0-9]+(\\.
[a-zA-Z0-9]+)+”;
相对不太精确的匹配”\\w+@\\w+(\\.\\w+)+”
只要有@就行:indexOf(“@”)!=-1
网页爬虫
//
网页爬虫
//
用于获取邮箱
import java.io.*;
import java.util.regex.*;
import java.ner.*;
class WebpageReptile
{
privatewebaddr ;
WebpageReptile(Stringwebaddr)
{
this.webaddr= webaddr ;
}
public staticvoid webpageReptile()throws Exception
{
URL url =new URL(webaddr);
URLConnectionconn = url.openConnerction();
BufferedReaderbufIn =
newBufferedReader(newInputStreamReader(conn.getInputStream));
Stringline = null;
StringmailReg = "\\w+@\\w+(\\.\\w+)+";
while((line= bufIn.readLine())!=null)
{
Matcherm = p.matcher(line);
while(m.find())
{
so.p(m.group)
}
}
}
}