基础知识

2.类

就是将我们具体的事物抽象出来
静态属性抽象成类的成员变量
动态属性抽象成类的成员方法

1 class Person {
2 private String name;
3 private int age;
4 ...说话,吃饭等成员方法    
5 }

3.成员变量和局部变量的区别

* A:在类中的位置不同
* 成员变量:在类中方法外
* 局部变量:在方法定义中或者方法声明上
* B:在内存中的位置不同
* 成员变量:在堆内存(成员变量属于对象,对象进堆内存)
* 局部变量:在栈内存(局部变量属于方法,方法进栈内存)
* C:生命周期不同
* 成员变量:随着对象的创建而存在,随着对象的消失而消失
* 局部变量:随着方法的调用而存在,随着方法的调用完毕而消失
* D:初始化值不同
* 成员变量:有默认初始化值
* 局部变量:没有默认初始化值,必须定义,赋值,然后才能使用
注意事项:
* 局部变量名称可以和成员变量名称一样,在方法中使用的时候,采用的是就近原则

1 String name;//成员变量
2 int num;//成员变量
3 public void speak() {
4 int num = 10;//局部变量
5 System.out.println(name);
6 System.out.println(num);
7 }

结果:
null
10

4.匿名对象

* A:什么是匿名对象
* 没有名字的对象 
* B:匿名对象应用场景
* a:调用方法,仅仅只调用一次的时候。
* 那么,这种匿名调用有什么好处吗?
* 节省代码 
* 注意:调用多次的时候,不适合。
匿名对象调用完毕就是垃圾,可以被垃圾回收器回收。
匿名对象只适合对方法的一次调用,因为调用多次就会产生多个对象,不如用有名字的对象
下面的代码毫无意义:
new Car().color = "red";
new Car().num = 8;
new Car().run();

5.封装

* A:封装概述
* 是指隐藏对象的属性和实现细节,仅对外提供公共访问方式
* B:封装好处
* 隐藏实现细节,提供公共的访问方式
* 提高了代码的复用性
* 提高安全性
* C:封装原则
* 将不需要对外提供的内容都隐藏起来
* 把属性隐藏,提供公共方法对其访问
封装在代码中无处不在,代码中每一个entity类都是封装来的

6.关键字private

private关键字特点
* a:是一个权限修饰符
* b:可以修饰成员变量和成员方法
* c:被其修饰的成员只能在本类中被访问
案例演示
* 封装和private的应用:
* A:把成员变量用private修饰
* B:提供对应的getXxx()和setXxx()方法

 1 class Person {
 2   String name;
 3   private int age;
 4   set,get方法    
 5 }
 6 class Demo1_Person {
 7   public static void main(String[] args) {
 8   Person p1 = new Person();
 9   p1.name = "张三";//这样是可以赋值的    
10   p1.age = -17;//不能赋值,因为age属性是私有的,不能在其它类中被访问,这里只能调用set方法赋值    
11   }
12 }
//注:私有化的成员变量,是可以在本类中直接使用的,如上name,也可以写this.name,this可以省略...

7.关键字this

* A:this关键字特点
* 代表当前对象的引用 
  this代表其所在函数所属对象的引用,哪个对象调用了this所在的函数,this就代表这个对象
* B:案例演示
* this的应用场景
* 用来区分成员变量和局部变量重名
案例:

1 class Person {
2     private String name;
3     private int age;    
4     public void setAge(int age) {//设置年龄
5         if (age > 0 && age < 200) {
6           this.age = age;//哪个对象来调用setAge()方法,this就代表哪个对象
7     }
8     }
9 }

8.构造方法

给对象的数据(属性)进行初始化
* B:构造方法格式特点
* a:方法名与类名相同
* b:没有返回值类型,连void都没有
* c:没有具体的返回值return;

 1 private String name;
 2 private int age;
 3 public Stu() {
 4 super();
 5 }
 6 public Stu(String name, int age) {
 7 super();
 8 this.name = name;
 9 this.age = age;
10 }

9.重载

定义:方法名相同,参数列表不一样的方法
无参构造有参构造就是重载

10.关键字static

意为静态
* A:static关键字的特点
* a:随着类的加载而加载
* b:优先于对象存在:随着字节码文件的加载而加载的,那时候还没有对象呢!
* c:被类的所有对象共享
* 举例:咱们班级的学生应该共用同一个班级编号。
* 其实这个特点也是在告诉我们什么时候使用静态?
* 如果某个成员变量是被所有对象共享的,那么它就应该定义为静态的
* 举例:
* 饮水机(用静态修饰)
* 水杯(不能用静态修饰)
* 共性用静态,特性用非静态
* d:可以通过类名调用
* 其实它本身也可以通过对象名调用
* 推荐使用类名调用,在工具类中常用
* 静态修饰的内容一般我们称其为:与类相关的,类成员(静态变量:类变量,静态方法:类方法)

面试题:

在静态方法中可以出现this这个关键字吗?
显然是不能的,this指的是一个具体的对象,而静态在加载到内存时还没有具体的对象,静态是随着类的加载而加载的,静态比对象优先存在
静态方法只能访问静态的成员变量和静态的成员方法
怎样理解:

1 class Demo {
2     int num1 = 10;
3     static int num2 = 20;
4     public static void print1() {
5         System.out.println(num1);
6         //该方法与变量num2都是静态的,类创建后它们就创建了,然而这时还没有变量num1(该变量是成员变量,当对象创建的时候才会产生),怎么访问,所以在静态中只能访问静态
7         System.out.println(num2);
8     }
9 }        

静态变量和成员变量的区别:
* 静态变量也叫类变量,成员变量也叫对象变量
* A:所属不同
* 静态变量属于类,所以也称为为类变量
* 成员变量属于对象,所以也称为实例变量(对象变量)
* B:内存中位置不同
* 静态变量存储于方法区的静态区
* 成员变量存储于堆内存
* C:内存出现时间不同
* 静态变量随着类的加载而加载,随着类的消失而消失
* 成员变量随着对象的创建而存在,随着对象的消失而消失
* D:调用不同
* 静态变量可以通过类名调用,也可以通过对象调用
* 成员变量只能通过对象名调用

面向对象02:

1.代码块

* A:代码块概述
* 在Java中,使用{}括起来的代码被称为代码块。
* B:代码块分类
* 根据其位置和声明的不同,可以分为局部代码块,构造代码块,静态代码块,同步代码块
* C:常见代码块的应用
* a:局部代码块(只要是和局部有关系的,都是和方法有关系的) 
* 在方法中出现;限定变量生命周期,及早释放,提高内存利用率
* b:构造代码块 (初始化块)
* 在类中方法外出现;多个构造方法方法中相同的代码存放到一起,每次调用构造都执行,并且在构造方法前执行
* c:静态代码块 
* 在类中方法外出现,并加上static修饰;用于给类进行初始化,在加载的时候就执行,并且只执行一次
* 一般用于加载驱动

所以有什么方法是要在类加载后就执行的(而且只需要执行一次)可以写成静态代码块

有时有些常量Map,List写法也可以用static,只需要在类存在的时候就给成员变量(这里是常量)赋值就可以了

这里使用static

如下:

public class PersonVo {
private int age;
private String name;
private String sex;

public static final Map<String, String> fenleiMap;

static {
System.out.println("----------static fenleiMap-----------");
Map<String, String> temp = new HashMap<>();
temp.put("A", "好人");
temp.put("B", "坏人");
fenleiMap = Collections.unmodifiableMap(temp);
}
}

案例:

 1 public class Mxdx {
 2     //构造块,每次执行构造方法,都会执行它,就是说每次创建新对象都会先执行这个
 3     {
 4         System.out.println("gou zhao kuai");
 5     }
 6     //类加载的时候就执行,只执行一次,一般用于加载驱动:如数据库连接
 7     static {
 8         System.out.println("jin tai kuai");
 9     }
10     
11     private String name;
12     private int age;
13     public Mxdx() {
14         super();
15         // TODO Auto-generated constructor stub
16         System.out.println("kon can");
17     }
18     public Mxdx(String name, int age) {
19         super();
20         this.name = name;
21         this.age = age;
22         System.out.println("you can");
23     }
...set,get方法 36 }
 1 public class MxdxTest {
 2     public static void main(String[] args) {
 3         Mxdx m1 = new Mxdx();
 4         m1.setName("张三");
 5         
 6         Mxdx m2 = new Mxdx();
 7         m2.setName("李四");
 8         
 9         Mxdx m3 = new Mxdx("王五", 11);
10     }
11 }

运行结果:
jin tai kuai
gou zhao kuai
kon can
gou zhao kuai
kon can
gou zhao kuai
you can

2.继承

让类与类之间产生关系,子父类关系
目的:子类继承父类的变量和方法 
继承的好处和弊端:
* A:继承的好处
* a:提高了代码的复用性,父类就是被复用的
* b:提高了代码的维护性
* c:让类与类之间产生了关系,是多态的前提
* B:继承的弊端
* 类的耦合性增强了。类与类之间的关系太紧密,一边添加属性,另一边就多了一个,有的时候是期望的,但是有的时候是不期望的
* 开发的原则:高内聚,低耦合。就是指自己完成事情的能力,自己能完成就不要麻烦别人
* 耦合:类与类的关系
Java中类的继承特点:
* A:Java中类的继承特点
* a:Java只支持单继承,不支持多继承。(一个儿子只能有一个爹,多继承是有安全隐患的,如A继承B,C,因为BC中属性可能是矛盾的,这样继承会有问题,所以不能多继承)
* b:Java支持多层继承(继承体系),如A继承B继承C,田园犬继承犬继承动物
继承的注意事项和什么时候使用:
* A:继承的注意事项
* a:子类只能继承父类所有非私有的成员(成员方法和成员变量)
* b:子类不能继承父类的构造方法,但是可以通过super关键字去访问父类构造方法。
* c:不要为了部分功能而去继承
* 项目经理 姓名 工号 工资 奖金
* 程序员 姓名 工号 工资
* B:什么时候使用继承
* 继承其实体现的是一种关系:"is a"。
Person
Student
Teacher
水果
苹果
香蕉
橘子
采用假设法。
如果有两个类A,B。只有他们符合A是B的一种,或者B是A的一种,就可以考虑使用继承。
案例:

 1 class Demo3_Extends {
 2     public static void main(String[] args) {
 3         Son s = new Son();
 4         s.show();
 5     }
 6 }
 7 class Father {
 8     private String name;
 9     private void show() {
10         System.out.println("Hello World!");
11     }
12 }
13 14 class Son extends Father {
15 }

面向对象03:

1.多态

所谓多态就是事物存在的多种形态
表现形式是父类引用指向子类对象
多态前提:
* a:要有继承关系
* b:要有方法重写
* c:要有父类引用指向子类对象
重写:
就是子类中写了和父类相同的方法,将父类方法覆盖
这样子类在调用该方法时,就直接调用自己的方法,而不是父类的方法
案例:

 1 class Demo1_Polymorphic {
 2     public static void main(String[] args) {
 3         Cat c = new Cat();
 4         c.eat();
 5 
 6         Animal a = new Cat();
 7                 //创建一个动物,这个动物是只猫,这没问题,父类引用指向子类对象
 8         a.eat();//这里结果是猫吃鱼
 9     }
10 }
11 class Animal {
12     public void eat() {
13         System.out.println("动物吃饭");
14     }
15 }
16 
17 class Cat extends Animal {
18     public void eat() {
19         System.out.println("猫吃鱼");
20     }
21 }

看看下面的例子:

 1 class SuperMan extends Person {
 2     String name = "superMan";
 3 
 4     public void talkTrade() {
 5         System.out.println("谈几个亿的大单子");
 6     }
 7 
 8     public void fly() {
 9         System.out.println("飞出去救人");
10     }
11 }
1 public class Person {
2     String name = "John";
3     public void talkTrade() {
4         System.out.println("谈生意");
5     }
6 }
 1 public class Demo3_SuperMan {
 2     public static void main(String[] args) {
 3         Person p = new SuperMan();//向上转型
 4         System.out.println(p.name);//没有用到多态,调用的是父类的属性        
 5         p.talkTrade();//只有这里用到了多态,因为只有这里运用的是重写的方法
 6         //p.fly(),能这样写吗?是不能的,因为超人被提升为人了,而父类是不能调用子类方法的,这里p是父类对象,只有当满足多态条件时,才会看成子类对象
 7         SuperMan sm = (SuperMan)p;//向下转型
 8         sm.fly();
 9     }
10 }

运行结果:

John
谈几个亿的大单子
飞出去救人

为什么会出现这个结果,注释中解释了

2.多态中向上转型和向下转型

Person p = new SuperMan();向上转型,超人提升为人,为什么叫向上转型,因为人是父类,是在上的
SuperMan sm = (SuperMan)p;向下转型,人转换为子类超人
3.多态的好处和弊端
* A:多态的好处
* a:提高了代码的维护性(继承保证)
* b:提高了代码的扩展性(由多态保证)
* B:案例演示
* 多态的好处
* 可以当作形式参数,可以接收任意子类对象,就是在方法中使用父类作为参数时,有时会用到多态
* C:多态的弊端
* 不能使用子类的特有属性和行为,上面代码已经演示了
 1     public static void method(Animal a) {    
 2                 //当作参数的时候用多态最好,因为扩展性强
 3                 //当传入对象是猫或者狗的时候,实际上Animal a = 猫,所以用到多态了
 4         //关键字 instanceof 判断前边的引用是否是后边的数据类型
 5         if (a instanceof Cat) {
 6             Cat c = (Cat)a;
 7             c.eat();
 8             c.catchMouse();
 9         }else if (a instanceof Dog) {
10             Dog d = (Dog)a;
11             d.eat();
12             d.lookHome();
13         }else {
14             a.eat();
15         }
16     }    

4.关键字abstract

意为抽象,就是看不懂,你不知道
* a:抽象类和抽象方法必须用abstract关键字修饰
* abstract class 类名 {}
* public abstract void eat();//不知道该方法具体是怎么实现的
//比如动物吃,你知道它吃什么吗?怎么吃?都不知道
* b:抽象类不一定有抽象方法,有抽象方法的类一定是抽象类或者是接口
* c:抽象类不能实例化那么,抽象类如何实例化呢?
* 按照多态的方式,由具体的子类实例化。其实这也是多态的一种,抽象类多态
* d:抽象类的子类
* 要么是抽象类
* 要么重写抽象类中的所有抽象方法

 1 abstract class Animal {                        //抽象类
 2     public abstract void eat();                //抽象方法,子类继承抽象类,抽象方法是强制要重写的,和接口一样,不重写,抽象还有什么意义
 3     public Animal() {
 4         System.out.println("父类空参构造");
 5     }
 6 }
 7 class Cat extends Animal {
 8     public Cat() {
 9         super();
10     }
11 
12     @Override
13     public void eat() {
14         // TODO Auto-generated method stub
15         System.out.println("mao ci yu");
16     }
17 }
18 class Demo1_Abstract {
19     public static void main(String[] args) {
20         //Animal a = new Animal();            //错误: Animal是抽象的; 无法实例化
21         Animal a = new Cat();                //父类引用指向子类对象
22         a.eat();
23     }
24 }
//可以把抽象类看作是接口,都是无法实例化的,都是子类必须重写方法的....

运行结果:

父类空参构造

mao ci yu

抽象类的成员特点:
* A:抽象类的成员特点
* a:成员变量:既可以是变量,也可以是常量。abstract是否可以修饰成员变量?不能修饰成员变量
* b:构造方法:有
* 用于子类访问父类数据的初始化
* c:成员方法:既可以是抽象的,也可以是非抽象的
* B:案例演示
* 抽象类的成员特点
* C:抽象类的成员方法特性:
* a:抽象方法,强制要求子类做的事情。
* b:非抽象方法,子类继承的事情,提高代码复用性

 1 abstract class Demo {
 2     int num1 = 10;//变量
 3     final int num2 = 20;//常量
 4 
 5     public Demo(){}//构造方法
 6 
 7     public void print() {//非抽象方法,子类可以直接使用
 8         System.out.println("我是码农");
 9     }
10 
11     public abstract void method();//抽象方法,子类必须实现
12 }
13 
14 class Test extends Demo {
15     public void method() {
16         System.out.println("绝地求生");
17     }
18 }

* A:面试题1
* 一个抽象类如果没有抽象方法,可不可以定义为抽象类?如果可以,有什么意义?
* 可以
* 这么做目的只有一个,就是不让其他类创建本类对象,交给子类完成
* B:面试题2
* abstract不能和哪些关键字共存
不能与static,final,final共存
abstract和static
被abstract修饰的方法没有方法体
被static修饰的可以用类名.调用,但是类名.调用没有实现的抽象方法有什么意义
abstract和final
被abstract修饰的方法强制子类重写
被final修饰的不让子类重写,所以他俩是矛盾
abstract和private
被abstract修饰的是为了让子类看到并强制重写
被private修饰不让子类访问,子类都不能访问了,还重写个啥啊

5.接口:

* A:接口概述
* 从狭义的角度讲就是指java中的interface
* 从广义的角度讲对外提供规则的都是接口 
* B:接口特点
* a:接口用关键字interface表示
* interface 接口名 {}
* b:类实现接口用implements表示
* class 类名 implements 接口名 {}
* c:接口不能实例化
* 那么,接口如何实例化呢?
* 按照多态的方式来实例化
* d:接口的子类
* a:可以是抽象类。但是意义不大
* b:可以是具体类。要重写接口中的所有抽象方法,代码中无处不在
* A:接口成员特点
* 成员变量只能是常量,并且是静态的并公共的
* 默认修饰符:public static final
* 构造方法:接口没有构造方法
* 成员方法:只能是抽象方法
* 默认修饰符:public abstract

1 public interface Inter {
2     public static final int num = 10;//这里写不写public static final都会默认加上
3     public abstract void print();//这里写不写public abstract都会默认加上,因为写接口本来就是为了实现的啊,会默认加上abstract
4 }
1 class Demo implements Inter {
2     public Demo() {
3         super();
4     }
5     public void print() {
6         //num = 20;num已经被final修饰了,不能重新赋值
7         System.out.println(num);
8     }
9 }
1 public class Demo2_Interface {
2     public static void main(String[] args) {
3         Demo d = new Demo();
4         d.print();
5         System.out.println(Inter.num);
6     }
7 }

运行结果:

10
10

类与类,类与接口的关系:
* a:类与类:
* 继承关系,只能单继承,可以多层继承
* b:类与接口:
* 实现关系,可以单实现,也可以多实现
* 并且还可以在继承一个类的同时实现多个接口

抽象类和接口的区别:

两者都会用到关键字abstract ,有什么区别呢

* A:成员区别
* 抽象类:
* 成员变量:可以变量,也可以常量
* 构造方法:有
* 成员方法:可以抽象,也可以非抽象
* 接口:
* 成员变量:只可以常量
* 成员方法:只可以抽象

在接口中变量和方法都作了限制

设计理念上的区别
* 抽象类 被继承体现的是:”is a”的关系。抽象类中定义的是该继承体系的共性功能,是为了给子类根据自身需要,重写重写抽象方法,所以抽象类是共性功能的提取
* 接口 被实现体现的是:”like a”的关系。接口中定义的是该继承体系的扩展功能,也就是说要扩展的时候常写一个接口,如果想要该功能就去实现这个接口
* 对事物本质的抽象用抽象类,对事物功能的扩展用接口

看看下面代码就明白了:

 1 abstract class Animal {
 2     private String name;                
 3     private int age;                    
 4     public Animal() {}                    
 5     public Animal(String name,int age) {
 6         this.name = name;
 7         this.age = age;
 8     }
 9 
10     public void setName(String name) {
11         this.name = name;
12     }
13 
14     public String getName() {            
15         return name;
16     }
17 
18     public void setAge(int age) {        
19         this.age = age;
20     }
21 
22     public int getAge() {                
23         return age;
24     }
25     public abstract void eat();        
26     public abstract void sleep();    
27 }
 1 class Cat extends Animal {
 2     public Cat() {}                    
 3     public Cat(String name,int age) {
 4         super(name,age);
 5     }
 6     public void eat() {
 7         System.out.println("猫吃鱼");
 8     }
 9     public void sleep() {
10         System.out.println("侧着睡");
11     }
12 }
1 interface Jumping {    
2     public void jump();
3 }
1 class JumpCat extends Cat implements Jumping {
2     public JumpCat() {}
3     public JumpCat(String name,int age) {
4         super(name,age);
5     }
6     public void jump() {
7         System.out.println("猫跳高");
8     }
9 }
 1 public class Test1_Animal {
 2     public static void main(String[] args) {
 3         Cat c = new Cat("加菲",8);
 4         c.eat();
 5         c.sleep();
 6         JumpCat jc = new JumpCat("跳高猫",3);
 7         jc.eat();
 8         jc.sleep();
 9         jc.jump();
10     }
11 }

运行结果:

猫吃鱼
侧着睡
猫吃鱼
侧着睡
猫跳高

现在看看这些面向对象中的设计,都是有道理的,都是观察现实中的事物,然后抽取出来的

为实现不同的功能而设计的

Java语言,不管是什么编程语言,这些设计者是真的厉害

posted @ 2018-05-07 17:32  0706jaro  阅读(178)  评论(0编辑  收藏  举报