Java 面向对象入门
来源:互联网 发布:淘宝的淘口令怎么取消 编辑:程序博客网 时间:2024/05/23 21:16
面向对象入门
@Author:云都小生
span {color: red;}
p {style=”font-size:22}
类与对象
现实生活中有各式各样的对象,有狗有猫有人,有树有花有草,我们所见到的东西,都是对象。这些对象有一些,拥有相同的属性和方法。例如说狗,它们同样有四条腿,两个眼睛,它们同样都会叫 Java是面向对象的编程语言,在Java中怎么实现面向对象编程呢?
public class Test{ public static void main(String[] args) { Dog dog = new Dog; }}//不同的类文件public class Dog { String color; String name; String sex; Dog(String color,String name,String sex){ //构造方法 this.color = color; this.name = name; this.sex = sex; } void run() { System.out.print("Dog in running···\n"); } void bray() { System.out.print("汪汪汪\n"); }}
在这个例子中,Dog就是一个类,在Dog里面有这么几个属性:color、name、sex,还有三个方法。一个是Dog的构造方法,另外两个方法是run和bray。
类与对象有什么关系,有什么区别?类其实就是一个模版,对象是根据这个模版创建出来的实例。对象创建之后,自动拥有类的所有属性和方法。类并不是实际存在的,对象才是在内存中实际存在的。new这个关键字,就是用来分配内存空间。一句话理解,类就是“人”,而对象是具体的“什么样的人”。
什么是构造方法?每个类都会有构造方法,我们可以通过构造方法,一开始就给对象里面的属性赋值。如果你没有构造方法,默认的就会有一个构造方法,就像这样 Dog(){} 构造方法可以被重载。可以看下面重载的相关知识点。
Dog(String name){}
this是一个关键字,这个this算是一个指针,指向对象本身。通过构造方法传进来的那
我们可以通过对象.属性的方式,来索引对象内部的属性。Dog.name 或者 Dog.sex
对象与对象变量这里还需要谈一个小细节,对象是在内存里面实实在在存在的,而对象变量,只是一个变量,指向内存中具体对象的数据。
引用类型的内存分析
之前我们经常用String类型,其实String是一个引用类型,什么意思呢?有过指针知识基础的人应该知道,如果你不知道,莫慌。String变量其实存储的并不是真正的字符串,而是字符串在内存中存在的地址。
程序占用内存的是有不同类型的:是堆、栈、全局区、常量区、程序代码区;
1. 堆一般由程序员分配;
2. 栈一般由编译器自动分配,存放参数值,局部变量的值等;
3. 全局变量和静态变量存放的地方;
4. 常量字符串存放的地方;
5. 程序代码区。
String str = “Cloudking”; 这个str其实是存放在栈,而字符串是存放再堆里面,str会存储字符串在内存常量区的地址,通过这个地址找到相应的数据。
而在类与对象中,也是这样。对象名存储的是整个对象数据在堆中的首地址,通过这个地址去索引相应的数据。Dog dog = new Dog(); dog会指向对象数据在堆中的地址。
面向对象基本特性——重载
同一个类里面,多个方法可以有相同的名字,只要它们的参数列表不同就可以,这种方式叫“方法重载”。
public class Dog { void printTest() { System.out.println("没有参数"); } void printTest(String name) { System.out.println(name); } void printTest(int id,String name) { System.out.print(id + "\n" + name); }}#main方法里面Dog dog = new Dog();dog.printTest("Cloudking");dog.printTest(123,"Cloudking");
编译器会根据调用方法的参数个数、参数类型等去逐个匹配,以选择对应的方法。还有几点需要注意:
· 构造方法也可以重载;
· 方法名称必须相同,才能够重载;
· 重载的方法除了方法名外,参数不能一模一样;
· 不能用返回值来进行重载。
面向对象基本特性——静态域与静态方法
静态域又称为类变量,所有的对象,都共享这一个类变量,修饰类变量的方法,就是用static,看实例。
public class Dog { private static int id;}
这样一来,所有由Dog new出来的对象,都指向这同一个变量id。静态方法,就是不能对对象进行操作的方法。一般用到静态方法,都有两点:
- 方法不需要访问对象状态;
- 只需要访问类的静态域。
public class Dog {
private static double x = 8.888;private static void Test(){ System.out.println(getX());}public static double getX() { return x;}public static void setX(double x) { Dog.x = x;}
}
//main
Dog dog1 = new Dog();
Dog dog2 = new Dog();
dog1.setX(12);
System.out.println(Dog.getX());- 只需要访问类的静态域。
还有一个小插曲,关于静态常量,我们用final来修饰常量,用static来修饰它是一个静态的常量。
public class Math{ ... public static final double PI = 3.14159265358979323846; ... }
本来加上final就修饰成常量了,再加上static,就不用每次都需要new一个对象才能使用这个常量。
面向对象特性——封装
面向对象的第一大特性——封装。这个词我们并不陌生,在面向对象中,封装指的是将细节包装、隐藏起来,防止该类的代码和数据被外部类定义的代码随机访问。这样一来,可以使代码变得安全(可靠)、更容易维护(重用性)。
以下把优点列出来:
1. 良好的封装能够减少耦合;<br/>2. 类内部的结构可以自由修改;<br/>3. 可以对成员变量进行更精确的控制;<br/>4. 隐藏信息,实现细节。<br/>
怎么对类中的属性进行封装呢?把类的属性设置为私有,对外提供“构造器”和“访问器”。
public class Dog { private String color; private String name; private String sex; Dog(String color,String name,String sex){ //构造方法 this.color = color; this.name = name; this.sex = sex; } void run() { System.out.print("Dog in running···\n"); } void bray() { System.out.print("汪汪汪\n"); }}
把类中的属性,都加上private这个权限修饰符,就会变成类私有的属性。如果你在该类的外部去访问、修改,就会出现错误。这样一来,我们就实现了属性隐藏,那怎么才能间接性的访问、修改它们。这里就涉及到了访问器和修改器,它们能让我们间接的访问、修改类中隐藏的属性。
public class Dog { private int id; private String name; Dog(int id,String name) { this.id = id; this.name = name; } public String getname() { return this.name; } public int getid() { return this.id; } public void setname(String name) { this.name = name; } public void setid(int id) { this.id = id; }}
看看这个类,把内部的属性用private隐藏了起来,通过private修饰的属性和方法,都只能在类内部被访问、修改,不能被外部直接访问(get)、修改(set)。这样做有什么好处呢?第一点,安全性,第二点,屏蔽细节。
如果用户在设置数值的时候随意输,你要怎么办?你要在哪里检查?我们来看一个set方法。
public void setid(int id){ if( id <= 100 && id >= 1) { this.id = id; } else { System.out.println("输入有误!"); }}
类内部的方法也可以被private修饰,被private修饰的方法,只能在类内部被使用。
面向对象特性——继承
动物界中存在这么一种情况,儿子往往会继承父母的优点,就像我们,我们有可能就继承了自己父母的许多特性。而在面向对象编程中,也有这么一个特性——继承。在Java中,类与类之间可以有继承的关系,子类可以继承父类的属性和方法。
public class Animal { String color; void bray() { System.out.println("bray~"); }}public class eatgrassAnimal extends Animal { void eat() { System.out.println("eat grass"); }}#maineatgrassAnimal d = new eatgrassAnimal();d.color = "yellow";d.bray();d.eat();
eatgrassAnimal从Animal类里继承,自动拥有了Animal类非private的属性和方法,它也可以拥有自己的属性和方法,作为对父类的扩展,继承可以增加程序的复用性。extends关键字用来修饰一个类从另一类中继承,Java中所有的类默认都从Object类继承。
java里只支持单继承,一个子类只能有一个父类,但是可以进行继承,简答的说,A可以从B继承,B可以从C继承,一代更比一代强。子类中如果想访问父类里面的对象,可以使用super的关键字。
public class Animal { String color; Animal(String color) { this.color = color; } void bray() { System.out.println("bray~"); }}public class eatgrassAnimal extends Animal{ String name; eatgrassAnimal(String color,String name) { super(color); this.name = name; } void eat() { System.out.println("eat grass"); } void bray() { super.bray(); System.out.println("eatgrassAnimal bray~"); }}#maineatgrassAnimal e = new eatgrassAnimal("yellow","羊");e.bray();
super可以调用父类的构造方法、调用父类的方法(当子类覆盖父类的方法时)、访问父类的数据域。
每个子类构造方法的第一条语句,都是隐含地调用super(),如果父类没有这种形式的构造函数,那么在编译的时候就会报错。
super()从子类中调用父类的构造方法,this()在同一类内调用其它方法。子类覆盖或重写了父类的方法,则只有使用 super 才能在子类中调用父类中的被重写的方法。
从本质上讲,this是一个指向本对象的指针, 然而super是一个Java关键字。
面向对象特性——多态
由于有了继承,就延伸出了另一种特性——多态。多个子类都从同一个父类继承,像食草动物、食肉动物,都是继承自动物。在我们在编写程序的过程中,并不知道什么时候会传过来食草动物的对象、什么时候会传过来食肉动物的对象,所以我们在调用方法的时候,总不能直接就对单一的对象进行处理吧。
假设食草动物、食肉动物都有同一个方法——run(),但是在我们在调用它们这个方法的时候,需要传入不同的对象,根据不同的对象去调用它们各自的run()方法。这个就是动态绑定,根据传入的对象,去调用属于它们各自的方法。
public class eatgrassAnimal extends Animal{ void eat() { System.out.println("eat grass"); }}public class eatmeatAnimal extends Animal { void eat() { System.out.println("eat meat"); }}public class Animal { void eat() { System.out.println("eat···"); }}public class Test{ public static void main(String[] args) { eatgrassAnimal g = new eatgrassAnimal(); eatmeatAnimal m = new eatmeatAnimal(); print(g); print(m); } static void print(Animal a) { a.eat(); }}
可以看到两个类eatgrassAnimal和eatmeatAnimal都是从Animal继承,都重写了Animal的eat()方法。当我们想根据传入的对象,调用它们具体的方法时,就可以写成pritn(Animal),父类引用指向子类对象。
多态的实现必须有三个条件:
1. 继承
2. 方法重写
3. 父类引用指向子类对象
现实中其实有很多多态的例子,我们能在word文档里面使用的快捷键,换到了桌口下面,也能使用快捷键,只是做出的反应不一样。
在游戏设计中,也会有多态设计的例子,例如说坦克和飞机,都是攻击性的机器,它们都有这样一个方法attack(攻击),但是它们攻击的方式都不一样,也就是方法里面实现的不一样。这样,调用attack()方法,我们就可以利用多态来实现。
public class Machine { void attack() { System.out.println("Attack中···"); }}public class Aircraft extends Machine { void attack() { System.out.println("战机导弹发射!"); }}public class Tanke extends Machine { void attack() { System.out.println("坦克炮弹发射!"); }}public class Test{ public static void main(String[] args) { Tanke t = new Tanke(); Aircraft a = new Aircraft(); Attack(t); Attack(a); } static void Attack(Machine m) { m.attack(); }}
面向对象特性——抽象类
抽象类和一般的类没有太大的区别,只是多了个抽象方法。类中有一部分不能确定——既需要这种功能,又没办法去定义主题,就可以写成抽象类。
抽象方法和抽象类都必须被abstract关键字修饰。抽象类中的抽象方法要被使用,必须由子类重写所有的抽象方法后才能调用。记住,是重写,不是纯粹的把代码复制,那样依旧是一个抽象类。
abstract class Test { abstract void test();}
这个Test抽象类,可以实现其他的很多方法,但是这里面只要有一个抽象方法,就必须被修饰成抽象类。并且,这类还不能被final修饰,抽象类就是要继承,然后让子类去实现抽象方法,其次,方法也不能被static和private修饰。static关键字会把方法修饰成公用,即使没有对象也能直接用,那样就没有意义了,如果是private,抽象方法就不能被子类继承了。
归根结底,当一个类里面有一些不被确定的方法时,就可以使用abstact来修饰,让它成为抽象类,然后让子类去实现这个抽象方法。
面向对象特性——接口
接口不是类,而是对类的一组需求描述。Java没有提供多继承的机制,没有办法同时继承两个类,但是Java却可以实现多个接口。一个接口只有方法的特征,而没有方法的实现,因此这些方法在不同的地方被实现时,可以具有完全不同的行为。(是不是感觉跟抽象类很像)
在Java中使用interface来定义一个接口,而使用implements来实现接口。
public interface Test{ public static final int num; //成员常量具有固定的修饰符:public static final public abstract void method; //成员函数具有固定的修饰符:public abstract }public class Testimpl implements Test{// 实现接口中的所有方法 .....}
接口的确跟抽象类很像,但是它本质上并不是类,而且,接口与接口之间可以是继承关系,而且可以实现多继承。接口比抽象类更抽象。
2017/9/2 22:52:38 @Author:云都小生
- Java面向对象入门
- Java面向对象入门
- Java 面向对象入门
- Java面向对象编程入门
- java入门(3)--面向对象
- java基础--面向对象入门
- Java面向对象入门(一)
- java入门6-面向对象
- Java入门:面向对象的思维方法
- Java面向对象编程的入门理解
- Java知识(008)--面向对象入门
- android入门学习-java面向对象基础
- Java入门_面向对象基本概念
- Java基本知识(连载)-面向对象入门
- 《java入门第一季》之面向对象
- Java学习2 面向对象程序设计入门
- Java实现面向对象编程(入门)
- Java入门代码示例--面向对象
- Python3 File(文件) 方法
- spring boot运行中遇到的问题
- javawebday07(dom和sax解析)
- Qt 中使用全局变量的方法
- 教你选择免费cad看图软件的操作和步骤
- Java 面向对象入门
- DbVisualizer使用Phoenix连接Hbase
- 数据之间的类型转换
- protobuf之string bytes的区别
- 单行与多行文本溢出显示省略号
- 使用popen时,若最多执行100次而不pclose,将会出错
- 2017qcon全球软件开发大会,100+国内外技术大咖已就位
- spark开发指南
- Linux系统用ssh-keygen生成公私钥