黑马程序员————学习日记【6】 【Java面向对象2】
2013-04-09 19:29
633 查看
------- android培训、java培训、期待与您交流! ----------
/* 将学生和工人的共性描述提取出来,单独进行描述。 只要让学生和工人与单独描述的这个类有关系,就可以了。 继承: 1、提高了代码的复用性 2、让类与类之间产生了关系。有了这个关系,才有了多态的特性。 注意:千万不要为了获取其他类的功能,简化代码而继承。 必须是类与类之间有所属关系才可以继承。所属关系是 is a。 备注:判断类与类之间是否有所属关系的方式: 那就先继承一下,继承完成后,子类应该具备父类中的内容, 那么就看一下父类中的内容是不是子类都应该具备,如父类 中有的功能不是子类该具备的,那么它们之间就不应有继承。 */ /* class C { void demo1(){} } class A extends C { //void demo1(){} void demo2(){} } class B extends C { //void demo1(){} void demo3(){} } */ //Java语言中:java只支持单继承,不支持多继承。 //多继承是一个类可以继承多个类。多继承容易带来安全隐患。 //即Student类能继承Person类,就不能继承其他类了。 //当多个父类中定义了相同功能,当功能内容不同时,子类对象 //不确定要运行哪一个。 //但是java保留了多继承机制,并用另一种体现形式来完成,多实现。 //java支持多层继承。也就是一个继承体系。 //如何使用一个继承体系中的功能呢? //想要使用体系,先查阅体系中父类的描述。因为父类中定义的是该体 //系中的共性功能。通过了解共性功能,就可以知道该体系的基本功能。 //那么这个体系已经可以基本使用了。 //那么在具体调用时,要创建最子类的对象,为什么呢? //一是因为有可能父类不能创建对象,如抽象类和接口。 //二是创建子类对象可以使用更多的功能。包括基本的也包括特有的。 //简单一句话:查阅父类功能,创建子类对象使用功能。 //日后在查阅java的体系结构的时候,就按照这种方法来思考。 //单继承和多继承怎么去区分? //记住:java中一个孩子只能有一个父亲,不允许有多个父亲。 /* 聚集:has a 谁是谁的一种,那叫继承;谁里面有谁,那叫聚集。 分为聚合和组合两种,它们的紧密联系程度稍有不同。 聚合:球员与球队的关系就是聚合关系。 即球员是球队中的一个,球队中有球员。 组合:事物的联系程度更紧密。 手、脚都是人身体的一部分。 与球员比,手和脚对身体的重要程度要比球员对球队高。 写继承的目的,在于描述现实生活中的事物。 有时候,用聚集的次数要比继承还要多一些。 */ class Person { String name; int age; } class Student extends Person { void study() { System.out.println("good study"); } } class Worker extends Person { void work() { System.out.println("good work"); } } class ExtendsDemo { public static void main(String[] args) { Student s = new Student(); s.name = "zhangsan"; } }
/* 子父类出现后,类成员的特点: 类中成员: 1、变量 2、函数 3、构造函数 1、变量 如果子类中出现非私有的同名成员变量时, 子类要访问本类中的变量,用this 子类要访问父类中的同名变量,用super super的使用和this的使用几乎一致 this代表的是本类对象的引用 super代表的是父类对象的引用 */ class Fu { int num = 4; } class Zi extends Fu { // int num = 5; void show() { System.out.println(num); } } class ExtendsDemo2 { public static void main(String[] args) { Zi z = new Zi(); z.show(); // System.out.println(z.num+"...."+z.num); } }
/* 2、子父类中的函数 当子类出现和父类一模一样的函数时, 当子类对象调用该函数,会运行子类函数的内容。 如同父类的函数被覆盖一样。 这种情况是函数的另一个特性:重写(覆盖) 父类的方法还在内存当中,没有运行而已。 当子类继承了父类,沿袭了父类的功能到子类中, 但是子类虽具备该功能,但是功能的内容却和父类 不一致,此时没有必要定义新功能,而是使用覆盖特性, 保留父类的功能定义,并重写功能内容。 覆盖注意事项: 1、子类覆盖父类,必须保证子类权限大于等于父类权限, 才可以覆盖,否则编译失败。 2、静态只能覆盖静态。 记住: 重载:只看同名函数的参数列表 重写:子父类要一模一样,包括返回值类型。 特殊情况:在多态中,父类方法的返回值类型和子类方法 的返回值类型是可以有不同的。但是,这两个 参数类型得有关系才行,待续。 */ class Fu { int show() { System.out.println("fu show");return 1; } void speak() { System.out.println("vb"); } } class Zi extends Fu { void speak() { System.out.println("java"); } void show() { System.out.println("zi show"); } } class ExtendsDemo3 { public static void main(String[] args) { Zi z = new Zi(); z.speak(); } } class Tel { void show() { System.out.println("number"); } } class NewTel extends Tel { void show() { // System.out.println("number"); super.show(); System.out.println("name"); System.out.println("pic"); } }
/* 3、子父类中的构造函数 问:构造函数可以覆盖吗? 答:不能,覆盖得一模一样才行,子父类构造函数不能 一模一样。因为构造函数是随着类名走的,子父类 类名不能一致。 在对子类对象进行初始化时,父类的构造函数也会运行, 那是因为子类的构造函数在默认的第一行有一条隐饰的 语句super(); super(); 会访问父类中空参数的构造函数。而且子类 中所有的构造函数默认第一行都是super(); 为什么子类一定要访问父类中的构造函数? 因为父类中的数据子类可以直接获取。所以子类对象 在建立时,需要先查看父类是如何对这些数据进行初始 化的。所以子类在对象初始化时,要先访问一下父类中 的构造函数。如果要访问父类中指定的构造函数,可以 通过手动定义super语句的方式来指定。 注意:super语句一定定义在子类构造函数的第一行 */ //子类的实例化过程 /* 结论: 子类的所有的构造函数,默认都会访问父类中空参数的 构造函数。因为子类每一个构造函数内的第一行都有一 句隐饰super(); 当父类中没有空参数的构造函数时,子类必须手动通过 super语句形式来指定访问父类中的构造函数。 当然:子类的构造函数第一行也可以手动指定this语句 来访问本类中的构造函数,子类中至少会有一个构造函数 会访问父类中的构造函数。 */ class Fu //extends Object { int num; Fu() { //super(); num = 60; System.out.println("fu run"); } Fu(int x) { System.out.println("fu...."+x); } } class Zi extends Fu { Zi() { //super(); //super(4); System.out.println("zi run"); } Zi(int x) { this(); //super(); //super(2); System.out.println("zi..."+x); } } class ExtendsDemo4 { public static void main(String[] args) { Zi z = new Zi(); System.out.println(z.num); } } class Person { private String name; Person(String name) { this.name = name; } void show(){} } class Student extends Person { Student(String name) { super(name); } void method() { super.show(); } }
/* final:最终。作为一个修饰符。 1、可以修饰类,函数,变量。 2、被final修饰的类不可以被继承。 为了避免被继承,被子类复写功能。 用final类,它不能有子类继承。 继承有一个弊端:它打破了封装性。 3、被final修饰的方法不可以被复写 4、被final修饰的变量是一个常量,只能 赋值一次,既可以修饰成员变量,又 可以修饰局部变量。 当在描述事物时,一些数据的出现 值是固定的, 那么此时为了增强阅读性,都给这些值起个名字, 方便阅读,而此值不需要改变,所以加final修饰 作为常量:常量的书写规范所有字母都大写,如果 由多个单词组成,单词间通过-连接。 以后,凡是在写代码的时候,出现了一些固定数据, 这些值不会变化,即使只出现了一次,也建议把此 数据起个名字,那样阅读性更好。前提是,数据不 能变,变了就是变量了。 而如果值不变化,并且在成员位置上,常常还加上 一个修饰符static。因为数据是固定的,不改了, 那就共享了,共享数据加static就可以了。如再加 上public ,此数据的权限就足够大了,就不用对象 访问了,类名就可以访问了。因为它static了,此 时public static final也可以称为全局常量。 5、内部类定义在类中的局部位置上时,只能访问该 局部被final修饰的局部变量。 备注:一旦看到final, 1、名称会有变化,大小写要区分,全都是大写 2、数据固定的时候写PI,起名字为了增强阅读性 写代码阅读性很重要 现在学类的时候有两个修饰符,public和final。 private是修饰成员的。 */ public class Demo { final int x = 3; public static final double PI = 3.14; final void show1() {} void show2() { final int y = 4; System.out.println(3.14); } } class SubDemo extends Demo { // void show1(){} } class FinalDemo { public static void main(String[] args) { System.out.println("Hello World!"); } }/* 假如在开发一个系统时需要对员工进行建模,员工包含 三个属性:姓名,工号及工资。经理也是员工,除了含 有员工的属性外,另外还有一个奖金属性。请使用继承 的思想设计出员工类和经理类。要求类中提供必要的方 法进行属性访问。 员工类:name id pay 经理类:继承了员工,并有自己特有的bonus(奖金) */ class Employee//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 Manager extends Employee { private int bonus; Manager(String name,String id,double pay,int bonus) { super(name,id,pay); this.bonus = bonus; } public void work() { System.out.println("manager work"); } } class pro extends Employee//professional 专业人士 { Pro(String name,String id,double pay) { super(name,id,pay); } public void work() { System.out.println("pro work"); } } class AbstractTest { public static void main(String[] args) { System.out.println("Hello World!"); } } //Employee此时是普通员工和经理向上抽取出来的东西, //经理和员工之间本身不具备继承关系,谁也不是谁的 //一种,他们都属于打工的人。打工的人具备什么属性 //,他们就具备什么属性。
/*
需求:获取一段程序运行的时间
原理:获取程序开始和结束的时间并相减即可
获取时间:System.currentTimeMillis();
当代码完成优化后,就可以解决这类问题。
这种方式,叫做模板方法设计模式。
什么是模板方法?
在定义功能时,功能的一部分是确定的,一部分是不确定的,而确定的部分在使用不确定的部分,
那么这时就将不确定的部分暴露出去,由该类的子类去完成。
这种设计模式提高了扩展性,也提高了复用性。
*/
abstract class GetTime
{
public final void getTime()
{
long start = System.currentTimeMillis();
runcode();
long end = System.currentTimeMillis();
System.out.println("毫秒:"+(end-start));
}
public abstract void runcode();
}
class SubTime extends GetTime
{
public void runcode()
{
long start = System.currentTimeMillis();
for(int x=0; x<4000;x++)
{
System.out.print(x);
}
}
}
class TemplateDemo
{
public static void main(String[] args)
{
// GetTime gt = new GetTime();
SubTime gt = new SubTime();
gt.getTime();
}
}
class Fu { static int num = 5; void method1() { System.out.println("fu method_1"); } void method2() { System.out.println("fu method_2"); } static void method4() { System.out.println("fu method_4"); } } class Zi extends Fu { static int num = 8; void method1() { System.out.println("zi method_1"); } void method3() { System.out.println("zi method_3"); } static void method4() { System.out.println("zi method_4"); } } class DuoTaiDemo4 { public static void main(String[] args) { // Fu f = new Zi(); // System.out.println(f.num); // // Zi z = new Zi(); // System.out.println(z.num); // f.method1(); // f.method2(); // f.method3(); Fu f = new Zi(); System.out.println(f.num); f.method4(); Zi z = new Zi(); z.method4(); /* 在多态中,成员变量的特点: 无论编译和运行,都参考左边(引用型变量所属的类)。 在多态中,静态成员函数的特点: 无论编译和运行,都参考左边。 在多态中成员函数(非静态)的特点: 在编译时期:参阅引用型变量所属的类中是否有调用的方法。 如果有,编译通过;如果没有,编译失败。 在运行时期:参阅对象所属的类中是否有调用的方法。 简单总结:成员函数在多态调用时,编译看左边,运行看右边。 */ // Zi z = new Zi(); // z.method1(); // z.method2(); // z.method3(); } } /* 问:父类和子类,有相同名称的成员变量,这两个变量也是 静态的,那么多态时,调用的打印结果是父的还是子的? 答:父的 */
/* 需求: 电脑运行实例, 电脑运行基于主板。 */ interface PCI { public void open(); public void close(); } class MainBoard { public void run() { System.out.println("mainboard run"); } public void usePCI(PCI p)//PCI p = new NetCard(); { //接口型引用指向自己的子类对象。 if(p!=null) { p.open(); p.close(); } } } class NetCard implements PCI { public void open() { System.out.println("netcard open"); } public void close() { System.out.println("netcard close"); } } class SoundCard implements PCI { public void open() { System.out.println("SoundCard open"); } public void close() { System.out.println("SoundCard close"); } } /* class MainBoard { public void run() { System.out.println("mainboard run"); } public void useNetCard(NetCard c) { c.open(); c.close(); } } class NetCard { public void open() { System.out.println("netcard open"); } public void close() { System.out.println("netcard close"); } } */ class DuoTaiDemo { public static void main(String[] args) { MainBoard mb = new MainBoard(); mb.run(); mb.usePCI(null); mb.usePCI(new NetCard()); mb.usePCI(new SoundCard()); } }
/* 需求:数据库的操作 数据是:用户信息 1、连接数据库JDBC Hibernate 2、操作数据库 c create r read u upate d delete 3、关闭数据库连接 */ interface UseInfoDao { public void add(User user); public void delete(User user); } class UserInfoByJDBC implements UserInofDao { public void add(User user) { 1、JDBC连接数据库 2、使用sql添加语句添加数据 3、关闭连接 } public void delete(User user) { 1、JDBC连接数据库 2、使用sql添加语句删除数据 3、关闭连接 } } class UserInfoByHibernate implements UserInfoDao { public void add(User user) { 1、Hibernate连接数据库 2、使用sql添加语句添加数据 3、关闭连接 } public void delete(User user) { 1、Hibernate连接数据库 2、使用sql添加语句删除数据 3、关闭连接 } } class DBOperate { public static void main(String[] args) { // UserInfoByJDBC ui = new UserInfoByJDBC(); // UserInfoByHibernate ui = new UserInfoByHibernate(); UserInfoDao ui= new UserInfoByJDBC(); ui.add(user); ui.delete(user); } }
/* Object:是所有对象的直接或者间接父类,传说中的上帝。 该类中定义的肯定是所有对象都具备的功能 Object类中已经提供了对 对象是否相同的比较方法 如果自定义类中也有比较相同的功能,没有必要重新定义 只要沿袭父类中的功能,建立自己特有比较内容即可。 这就是覆盖。 */ class Demo //extends Object { private int num; Demo(int num) { this.num = num; } public boolean equals(Object obj)//Object obj = new Demo(); { if(!(obj instanceof Demo)) return false; Demo d = (Demo)obj; return this.num == d.num; } /* public boolean compare(Demo d) { return this.num==d.num; } */ public String toString() { return "demo:"+num; } } class Person { } class ObjectDemo { public static void main(String[] args) { Demo d1 = new Demo(4); System.out.println(d1.toString()); Demo d2 = new Demo(7); System.out.println(d2.toString()); // Demo d2 = new Demo(5); // Class c = d1.getClass(); // // System.out.println(c.getName()); // System.out.println(c.getName()+"@@"+Integer.toHexString(d1.hashCode())); // Person p = new Person(); // System.out.println(d1.equals(p)); } }
相关文章推荐
- 黑马程序员————学习日记【5】 【Java面向对象1】
- 黑马程序员_Java学习日记2_面向对象总结1
- 黑马程序员_Java学习日记3_面向对象总结2
- 黑马程序员_Java学习日记4_面向对象总结3
- 黑马程序员--【学习日记四】——java面向对象(二)
- 黑马程序员_Java学习日记5_面向对象总结4
- 黑马程序员——学习日记5 java面向对象基础
- 黑马程序员——学习日记7 java面向对象之封装
- 黑马程序员--面向对象第二部分-内部类、异常--java学习日记6(基础知识)
- 黑马程序员--面向对象第一部分--java学习日记4(基础知识)
- 黑马程序员--Java学习笔记之面向对象思想(多态、内部类、匿名内部类、异常类)
- Java学习日记----面向对象2
- 黑马程序员Java培训、Android培训-Java 学习过程记录_面向对象上
- java学习日记_36:面向对象之继承中构造方法的关系
- 黑马程序员——学习笔记05.java面向对象
- 黑马程序员—4—Java基础: 面向对象继承学习笔记和学习心得体会
- java学习日记_16:面向对象之匿名对象。07.03
- java学习日记_21:面向对象之this关键字的内存示意图。07.09
- 黑马程序员---java学习笔记之面向对象知识点2
- 黑马程序员_java面向对象学习笔记