面向对象,呃,别给我说程序员找不到对象,那是windows才会出现的情况~~~
就简单记下笔记什么的吧。
1、关于定义和赋值
之前总是搞混淆,说到底是没有搞清楚。
shit bigOne=new shit();
类型 变量名 定义
所以应该是先写后面——定义——new 类名();然后是前面,赋值给一个变量;然后最前面,该变量的数据类型,这里,数据类型就是该类。
2、局部变量和成员变量
遵循就近原则,即局部变量和成员变量重复时,以局部变量为准。
3、关于构造方法
其实上面定义对象的时候,最后面那个不是变量,不是类,是该类的构造方法!!!
所以有参的对象定义,也就是在有参的构造函数的调用。
所以可以直接通过有参构造函数进行输入,同时可以进行输入控制——安全性,正确性等。
另外,关于有参和无参并存:
package imooc2; public class telephone { //属性 double size; String color; double cpu; double price; //方法 void sendMessage(){ System.out.println("Shit!"+size+color+cpu+price); } public telephone(){ System.out.println("无参构造方法执行!"); } public telephone(double sizeIn,String colorIn,double cpuIn,double priceIn){ size=sizeIn; color=colorIn; cpu=cpuIn; price=priceIn; System.out.println("有参构造方法执行"); } }
package imooc2; public class initialTelephone { public static void main(String[] args) { // TODO Auto-generated method stub telephone phone = new telephone(1,"black",2.3,1500); phone.sendMessage(); phone.color="white"; phone.cpu = 1.3; phone.sendMessage(); telephone phone2 = new telephone(); phone2.sendMessage(); } }
4、关于静态变量
静态成员属于整个类,当系统第一次使用该类时,就会为其分配内存空间直到该类被卸载才会进行资源回收。
同样,静态方法也会有特殊情况:
与静态变量一样,我们也可以使用 static 修饰方法,称为静态方法或类方法。其实之前我们一直写的 main 方法就是静态方法。静态方法的使用如:
需要注意:
1) 静态方法中可以直接调用同类中的静态成员,但不能直接调用非静态成员。如:
如果希望在静态方法中调用非静态变量,可以通过创建类的对象,然后通过对象来访问非静态变量。如:
2) 在普通成员方法中,则可以直接访问同类的非静态变量和静态变量,如下所示:
3) 静态方法中不能直接调用非静态方法,需要通过对象来访问非静态方法。如:
与静态变量一样,我们也可以使用 static 修饰方法,称为静态方法或类方法。其实之前我们一直写的 main 方法就是静态方法。静态方法的使用如:
需要注意:
1)静态方法中可以直接调用同类中的静态成员,但不能直接调用非静态成员。如:
如果希望在静态方法中调用非静态变量,可以通过创建类的对象,然后通过对象来访问非静态变量。如:
2) 在普通成员方法中,则可以直接访问同类的非静态变量和静态变量,如下所示:
3) 静态方法中不能直接调用非静态方法,需要通过对象来访问非静态方法。
public class HelloWorld { // 定义静态变量score1 static int score1 = 86; // 定义静态变量score2 static int score2 = 92; // 定义静态方法sum,计算成绩总分,并返回总分 public static int sum() { int sum = score1+score2; return sum; } public static void main(String[] args) { // 调用静态方法sum并接收返回值 int allScore = HelloWorld.sum(); System.out.println("总分:" + allScore); } }
5、关于静态初始化块
这个我也是第一次知道,有点好玩,也是初始化块——》静态初始化块的
public class HelloWorld { String name; // 声明变量name String sex; // 声明变量sex static int age;// 声明静态变量age // 构造方法 public HelloWorld() { System.out.println("通过构造方法初始化name"); name = "tom"; } // 初始化块 { System.out.println("通过初始化块初始化sex"); sex = "男"; } // 静态初始化块 static { System.out.println("通过静态初始化块初始化age"); age = 20; } public void show() { System.out.println("姓名:" + name + ",性别:" + sex + ",年龄:" + age); } public static void main(String[] args) { // 创建对象 HelloWorld hello = new HelloWorld(); // 调用对象的show方法 hello.show(); } }
通过输出结果,我们可以看到,程序运行时静态初始化块最先被执行,然后执行普通初始化块,最后才执行构造方法。
需要特别注意:静态初始化块只在类加载时执行,且只会执行一次,同时静态初始化块只能给静态变量赋值,不能初始化普通的成员变量。
6、关于封装
对象的三大特性:封装、继承和多态!
封装:封装是个动词,动词就有对象,这里的对象就是对象,也就是把对象进行封装。什么叫做对象的封装呢?就是外部不能直接访问内部属性。类比电子元器件的封装,也就是用户只能通过接口插口等对其进行访问,不能直接接触其中的元器件。
好处自然不用说。
另外,封装三大步:private属性——》set和get方法设定——》输入输出控制;
package imooc2; public class telephone { //属性 private double size; private String color; private double cpu; private double price; //方法 public double getSize(){ return size; } public void setSize(double sizeInput){ size=sizeInput; } public String getColor(){ return color; } public void setColor(String colorInput){ color=colorInput; } void sendMessage(){ System.out.println("Shit!"+size+color+cpu+price); } public telephone(){ System.out.println("无参构造方法执行!"); } public telephone(double sizeIn,String colorIn,double cpuIn,double priceIn){ size=sizeIn; color=colorIn; cpu=cpuIn; price=priceIn; System.out.println("有参构造方法执行"); } }
7、关于包
包也可以看成是一种封装,只不过对象是各种类,也就是说包是各种类的文件夹。
包的存在是重名问题得到解决——比如你我都有一个姐姐,但定义一个类文件的时候,重名的是不能出现在同一个包的,所以有子包等概念出现。
这里就可以有两个telephone.java;
调用的话,就在头输入import即可
package com.imooc; import com.imooc.second.telephone;
8、访问修饰符
一图以敝之
9、关于this关键字
this表示当前对象,于是setter和getter中就经常使用this了。
另外,eclipse中自带生成setter和getter。
于是
public double getCpu() { return cpu; } public void setCpu(double cpu) { this.cpu = cpu; }
10、关于内部类
即类中类,关键就是用一个关键字Inner
//外部类HelloWorld public class HelloWorld { // 内部类Inner,类Inner在类HelloWorld的内部 public class Inner { // 内部类的方法 public void show() { System.out.println("welcome to imooc!"); } } public static void main(String[] args) { // 创建外部类对象 HelloWorld hello = new HelloWorld(); // 创建内部类对象 Inner i = hello.new Inner(); // 调用内部类对象的方法 i.show(); } }
内部类的存在原因是更好的封装
//外部类HelloWorld public class HelloWorld{ //外部类的私有属性name private String name = "imooc"; //外部类的成员属性 int age = 20; //成员内部类Inner public class Inner { String name = "爱慕课"; //内部类中的方法 public void show() { System.out.println("外部类中的name:" + HelloWorld.this.name ); System.out.println("内部类中的name:" + name ); System.out.println("外部类中的age:" + age); } } //测试成员内部类 public static void main(String[] args) { //创建外部类的对象 HelloWorld o = new HelloWorld (); //创建内部类的对象 Inner inn = o.new Inner() ; //调用内部类对象的show方法 inn.show(); } }
以及静态内部类
//外部类 public class HelloWorld { // 外部类中的静态变量score private static int score = 84; // 创建静态内部类 public static class SInner { // 内部类中的变量score int score = 91; public void show() { System.out.println("访问外部类中的score:" + HelloWorld.score ); System.out.println("访问内部类中的score:" + score); } } // 测试静态内部类 public static void main(String[] args) { // 直接创建内部类的对象 SInner si = new SInner(); // 调用show方法 si.show(); } }
以及方法内部类,也就是方法中定义内部类,有点繁琐,搞清楚调用的过程就行了
//外部类 public class HelloWorld { private String name = "爱慕课"; // 外部类中的show方法 public void show() { // 定义方法内部类 class MInner { int score = 83; public int getScore() { return score + 10; } } // 创建方法内部类的对象 MInner mi = new MInner(); // 调用内部类的方法 mi.getScore(); System.out.println("姓名:" + name + " 加分后的成绩:" + newScore); } // 测试方法内部类 public static void main(String[] args) { // 创建外部类的对象 HelloWorld mo = new HelloWorld(); // 调用外部类的方法 mo.show(); } }
11、关于继承
就是子类继承父类的属性和方法,说白了就是代码复用,就是程序员懒省事儿,为了代码整洁所做的工作。
需要注意父类的private是继承不到的。
实际上初始化一个子类对象,是先初始化父类对象的属性和构造方法,然后是子类的属性和构造方法!
可以使用super关键词调用父类的方法和属性,注意super无法在static的方法中调用,比如主函数。
12、关于重写
重写,也是一个动词,对象就是方法,是父类的方法。
就是子类对父类的方法不满意,重新书写该方法。
需要注意的是重写要求函数投是要求完全相同的,才能实现重写。
13、final关键字
14、关于Object类
所有类在没有强调父类时,默认的父类都是Object类!
Object类中有两个常用到的方法,toString()和equals();前者默认返回对象地址信息,后者默认对比两个对象引用地址是否相同;
由于对父类这两个方法不满意,所以我们在子类中进行重写;
这两个特殊的重写,直接交给eclipse,方法和上面那个一样,结果如下
package com.jicheng; public class Dog extends Animal { public int age=10; @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + age; return result; } @Override public boolean equals(Object obj) { if (this == obj)//引用地址 return true; if (obj == null)//比较空值 return false; if (getClass() != obj.getClass())//类对象,就是把类的情况作为对象,类的类型是否相同 return false; Dog other = (Dog) obj; if (age != other.age)//属性值 return false; return true; } public void eat(){ } @Override public String toString() { return "Dog [age=" + age + "]"; } }
主函数
package com.jicheng; public class initial { public static void main(String[] args) { // TODO Auto-generated method stub Dog dd=new Dog(); System.out.println(dd); Dog dog = new Dog(); // if(dog==dd){ if(dog.equals(dd)){ System.out.println("yes"); }else{ System.out.println("no"); } } }
15、关于多态
多态,一个形容词,就是说多种形态,那么形容的对象是?是对象。也就是说对象具有多种形态。
那么,对象具有多种形态,其实说的是对象的引用和方法具有多种形态
直观的看比较抽象,给出代码示例
package com.duotai; public class initial { public static void main(String[] args) { // TODO Auto-generated method stub Animal obj1 = new Animal(); Animal obj2 = new Dog();//父类的引用可以指向子类的对象 Dog obj3 = new Dog(); // Dog obj4 = new Animal();//错误 obj1.eat(); obj2.eat();//同样是父类的引用,但指向不同结果不同,称为方法的多态 } }
package com.duotai; public class Animal { public void eat(){ System.out.println("Can eat"); } }
package com.duotai; public class Dog extends Animal { public void eat(){ System.out.println("Dog eats meat"); } }
16、关于引用类型转换
这里出现了父类引用子类的情况,也就是说有引用类型转换的情况了。
关于引用类型转换,分为向上转换/隐式转换和向下转换/强制转换;
考虑向上转换为把水杯里的水倒回水壶,所以一般都是没有问题的;向下则相反,会出现问题,于是会有强制转换的需求。
package com.duotai; public class initial { public static void main(String[] args) { // TODO Auto-generated method stub Dog dog = new Dog(); Animal animal = dog;//向上转换 // Dog dog2 = animal;//直接的向下转换,不被允许 Dog dog2 = (Dog)animal;//强制的向下转换,可以执行 Cat cat = (Cat)animal;//同样可以执行,但会出现编译问题 } }
所以,一般使用强制使用的,需要先进行判断,用instanceof
package com.duotai; public class initial { public static void main(String[] args) { // TODO Auto-generated method stub Dog dog = new Dog(); Animal animal = dog;//向上转换 if(animal instanceof Dog){ Dog dog2 = (Dog)animal; }else{ System.out.println("Shit"); } if(animal instanceof Cat){ Cat cat = (Cat)animal; }else{ System.out.println("Shit"); } } }
17、关于抽象类
说到引用类型转换,有一个常用的场景:抽象类。
抽象对应具体,也就是说抽象的类;抽象类不关注子类的具体实现,只规定子类应该有什么样的方法!!
package com.chouxianglei; public abstract class Telephone { public abstract void call(); public abstract void message(); }
子类应该继承它
package com.chouxianglei; public class cellPhone extends Telephone { @Override public void call() { // TODO Auto-generated method stub System.out.println("键盘打电话"); } @Override public void message() { // TODO Auto-generated method stub System.out.println("键盘发短信"); } }
使用的时候就可以父类引用子类,注意这里父类不能引用自己
package com.chouxianglei; public class initail { public static void main(String[] args) { // TODO Auto-generated method stub Telephone telephone = new cellPhone(); telephone.call(); Telephone t2 = new smartPhone(); t2.call(); t2.message(); } }
18、关于接口
有了抽象类的概念,就不得不提一下接口的概念。
接口和抽象类类似,都是一种规范,但更加灵活,更加省事儿——比如有相同特征的,就可以针对相同特征设立接口,接口可以对接多个父接口,接口中都是abstract的,但不需要自己进行书写;
所以举例子,PSP和智能手机都有玩游戏的特征,但智能手机继承自手机父类,PSP继承自游戏机父类,但共同的特征是一个接口
package com.chouxianglei; public interface IPlayGame { public void playGame(); }
注意:接口的命名一般以I开头,以和其他类进行区分;
package com.chouxianglei; public class PSP implements IPlayGame { @Override public void playGame() { // TODO Auto-generated method stub System.out.println("PSP可以玩游戏"); } }
有父类的一定写在接口前面
package com.chouxianglei; public class smartPhone extends Telephone implements IPlayGame{ @Override public void call() { // TODO Auto-generated method stub System.out.println("触摸屏打电话"); } @Override public void message() { // TODO Auto-generated method stub System.out.println("触摸屏发短信"); } public void playGame(){ System.out.println("手机可以玩游戏"); } }
引用中,接口还是看成是父类的,依然可以父类引用子类
package com.chouxianglei; public class initail { public static void main(String[] args) { // TODO Auto-generated method stub Telephone telephone = new cellPhone(); telephone.call(); Telephone t2 = new smartPhone(); t2.call(); t2.message(); IPlayGame psp = new PSP(); psp.playGame(); IPlayGame s1 = new smartPhone(); s1.playGame(); //匿名内部类 IPlayGame tt = new IPlayGame(){ public void playGame(){ System.out.println("匿名内部类使用"); } }; tt.playGame(); new IPlayGame(){ public void playGame(){ System.out.println("匿名内部类使用2"); } }.playGame(); } }
最后两段是匿名内部类,即在程序中直接进行定义的类,直接使用!
19、关于UML
初级的程序员能看懂这种设计类图形语言就行了!
常见三种图:类图,用例图,序列图。
TMUML还能直接生成语言,天。。。
可以用visio画图http://blog.csdn.net/hyman_c/article/details/52586241