—面向对象(上)
一.面向对象的概念及思考方式
面向对象的理解:是一种编程思想,他将对象作为解决问题的基本元素,利用对象与对象之间的相互作用来设计程序。
2.面向对象的思考方式:(1)首先确定问题域中的对象
(2)确定对象的特征与功能
(3)了解对象与对象之间的关系
例:设计一个五子棋游戏的对象:·黑白双方对象 ·绘制棋盘 ·输赢规则
二.类与对象
1.对象:用来描述客观事物的一个实体,由一组属性和行为构成。
2.类:(1)是一个模板,他描述一类对象的行为和状态。
(2)类定义对象将会拥有的特征(属性)和行为(方法)
(3)类是对象的类型,和int类型不一样
3.对比: · 类是抽象概念
· 对象是实例
三.类与对象的创建
1.定义类的语法:(加static属于类)
格式:[访问修饰符] class 类名{
放属性和方法的声明
}
例:创建一个person类
package org.west;
public class Person {
int age;
public void say(){
System.out.println("大家好,我今年"+age+"岁了");
}
}
2.定义成员变量的定义:
(1)成员变量的语法:
格式:[访问修饰符] 数据类型 成员变量名 [=初始值]
(2)成员变量可以使用Java中的任何数据类型(基本类型和引用类型)
(3)在定义成员变量是可以对其进行初始化,若不进行初始化,编译器会用默认的初值进行初始化
(4)成员变量的作用域是整个类体
3.成员变量与局部变量的对比:
比较 | 成员变量 | 局部变量 |
定义位置 | 直接在类中定义 | 定义在方法中 |
声明赋值 | 可以在声明时赋初始值;若不赋值,会有默认初始值,引用类型的值为null | 在使用前需要赋值 |
作用域 | 在整个类内部都是可见的,所有成员方法都可以使用它,如果访问权限允许,还可以在类外部使用 | 仅限于定义它的方法,在该方法外无法访问它 |
*注意:(1)在同一个方法中,不允许有同名的局部变量。在不同的方法中,可以有同名的局部变量
(2)局部变量可以和成员变量同名,并且在使用时,局部变量具有更高的优先级
4.初始化与实例化:
初始化:有之后进行基本操作
实例化:一个从无到有从0~1的过程
5.类种方法的定义:
(1)语法:[访问修饰符] 返回值类型 数据类型(行参列表){
// 实现语句
}
例:在person类中定义一个say方法(红色标记)
package org.west;
public class Person {
int age;
public void say(){
System.out.println("大家好,我今年"+age+"岁了");
}
}
6.对象的产生与使用:
(1)根据设计好的类来设计一个对象:利用类关键词调用类的构造方法就可以创建该类的一个对象
例:以上面的程序例子为例创建一个对象
Person per=new Person();
此例中我们就创建了一个Person中的对象per
(2)构造方法:
·构造方法与类名相同,并且没有返回值,不需要加void
·构造方法的作用在于构造并初始化对象
·每一个类中至少包含一个构造方法
(3)构造方法分为:默认构造方法(无参构造,若是不写构造方法,编译器会自动生成一个无参构造,Java都要求有构造方法),带 参 数构造的方法
*注意:若是类中有我们写的构造方法时,编译器就不会在自动生成无参构造
四.方法的重载(overloading)
1.方法重载:同一个类中,方法名相同,参数列表不同(参数类型不同、参数个数不同、参数顺序不同)
2.方法重载与返回值类型无关
例:
1)public void study(String name){}
public void study(int hours){}
2)public void study(String name){}
public String study(String n){}
3)public void study(String name){}
public void study(String name, int age){}
4)public Student(String name){}
public Student(String name, int age){}
#重载解析:
方法名相同中参数类型不同,有返回值,所以是方法重载
方法名相同,参数类型相同,返回值类型不同,但是方法重载与返回值类型无关,所以不是方法重载
方法名相同,参数个数不同,有返回值类型,所以是方法重载
方法名相同,参数个数不同,无返回值类型,所以是构造方法重载
This关键字
1.每个类的每个非静态方法(没有被static修饰)都会隐含一个this引用名称,它指向调用这个方法的对象(当前对象)。
2.当在方法中使用本类的非static属性时,都会隐含地使用this名称。
3.this可以看作是一个变量,它的值就是当前对象的引用
4.this关键字的用法
(1)当类中某个非静态方法的参数名跟类的某个成员变量名相同时,为避免参数作用范围覆盖成员变量作用范围,必须明确的使用this关键字来指定成员变量
(2)如果某个构造方法的第一条语句具有形式(this…..),那么这个构造方法将调用本类中其他构造方法(调用其他构造方法,需要在其他构造方法中输出)
例:
package org.west;
public class Person {
String name;
String sex;
int age;
public Person() {
System.out.println("无参构造》》》》");
System.out.println("调用了无参构造方法!!!!!");
}
public Person(String name, String sex) {
this();
System.out.println("调用了 两参构造方法!!!!!");
this.name = name;
this.sex = sex;
}
public Person(String name, String sex, int age) {
this(name,sex);
this.age = age;
}
public void say(){
System.out.println("大家好,我叫"+this.name+"今年"+this.age+"岁了,性别"+this.sex);
}
}
*解析:×××标记的是作用一,使用this关键字来指定成员变量
蓝色标记的是调用构造方法
二.Static关键字
1. 在类中,用static声明的成员变量为静态成员变量,它是该类的公用变量,对于该类的所有对象来说,static成员变量只有一份。
2.用static声明的方法为静态方法,该方法独立于类的实例,所以也叫类方法。
(1)静态方法中只能直接调用本类中其他的静态成员(变量和方法)。
(2)静态方法中不能使用this和super关键字。
3.静态成员可以通过类名(不需要实例化)或类的实例去访问。
4.静态代码块:
(1)在类中可以使用不包含在任何方法中的静态代码块(static block),当类被JVM载入时,静态代码块被执行,且只被执行一次。
(2)静态代码块经常用来初始化类的静态成员变量。
格式: static{
// 静态代码块内容
}
例1:静态变量与静态方法
package staticdemo;
public class Person{
String name;
int age;
static int count; // 静态成员变量属于类的,对于所有该类的对象是公用的
public Person(){
count++;
}
public Person(String name,int age){
count++;
this.name=name;
this.age=age;
}
public static int getStaticCount(){
return count;
}
public void say(){
System.out.println("我叫"+this.name+";今年"+this.age+"岁了");
}
}
例2.静态代码块
package staticdemo;
public class StaticBlock {
static String note;
static int count;
public StaticBlock(){
System.out.println("无参构造...");
}
static{
System.out.println("这是静态代码块中的内容...");
note="备注";
count=2;
System.out.println("初始化后的note的值为:"+note);
System.out.println("初始化后的count的值为:"+count);
}
public static void main(String[] args) {
System.out.println("这是main方法");
}
}
5.静态区图:
三.封装性
1.封装:(1)对外部不可见,隐藏对象的属性和实现细节
(2)好处:隐藏实现类的细节,让使用者只能通过程序员规定的方法来访问数据,可以方便的加入存取控制语句,限制不合理操作
2.封装性的体现:
(1)类的封装(属性、方法都存在于某个类中)
(2)对字段的封装
·字段设置为私有(private)
·添加get /set 方法
(3)访问修饰符的限制,保证数据的安全
例:
Student类部分:
package org.west;
public class Student {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
if(age>=30){
System.out.println("年龄有误!!");
}else{
this.age = age;
}
}
public void say(){
System.out.println("大家好!我叫"+name+",今年"+age+"岁了");
}
}
# 利用private进行属性私有化,再用get/set方法来获取和设置属性的值
主函数部分:
package org.west;
public class StudentTest {
public static void main(String[] args) {
Student stu=new Student();
stu.setName("张三");
stu.setAge(18);
stu.say();
}
}
利用主函数new对象,并调用方法
四.继承性
1.<1>继承是一个类继承另一个类的,这个类拥有父类可以被继承的成员
<2>类的方法和属性都可以被继承
·私有的属性和方法不能被继承
·构造方法不能被继承
<3>继承是面向对象的特征之一
<4>实现继承的类被称为子类,被继承的类被称为父类,也叫基类或超类
<5>继承的好处:(1)实现代码的重现扩展。(2)模拟现实世界中的关系。
(3)结构更加清晰
<6>继承具有传递性
<7>单继承性:
(1)在java中一个类只能有一个父类,这就是Java的“单继承性”。
(2)java.lang.Object类是所有类的父类
2.使用继承:
<1>要继承一个类,可以使用extends关键字,意味着扩展父类的功能。
<2>类继承的基本语法:
[修饰符] <子类name> class extends <父类name>(){
语句…………..
}
例:动物类
package org.west;
public class Animal {
String name;
public void shout(){
System.out.println("动物发出叫声!!!!");
}
}
狗类继承动物类:
package org.west;
public class Dog extends Animal{
public void printName(){
System.out.println("此狗的名字是"+name);
}
}
测试类:
package org.west;
public class ExdentsTest {
public static void main(String[] args) {
Dog dog=new Dog();
dog.name="Tom";
dog.shout();
dog.printName();
}
}
*此例中是为Dog类继承Animal类
五.super关键字
1.在Java类中用super来引用父类的成员
·super可用于访问父类中定义的属性
·super可用于调用父类中定义的成员方法
Super.成员变量
Super.成员方法(参数1,参数2….)
例:定义动物类
package org.west;
public class Animal {
String name="动物";
public void shout(){
System.out.println("动物发出叫声!!!!");
}
}
定义狗类继承动物类:
package org.west;
public class Dog extends Animal{
String name="犬类";
public void shout (){
super.shout();
}
public void printName(){
System.out.println("此狗的名字是"+super.name);
}
}
定义测试类:
package org.west;
public class ExdentsTest {
public static void main(String[] args) {
Dog dog=new Dog();
dog.shout();
dog.printName();
}
}
此例中super调用了父类的方法和属性
·super(…)可用于在子类构造方法中调用父类的构造方法
Super.(参数1,参数2……)
Class Father{
private int n;
public Father(){
System.out.println(“父类无参构造”);
}
public Father(int n){
this.n=n;
System.out.println(“父类中带参构造”+n);
}
}
class Child extends Father{
private int n;
public Child(){
super(300);
System.out.println(“子类无参构造”);
}
public Child(int n){
this.n=n;
System.out.println(“子类带参构造”+n);
}
}
*注意:(1)当子类和父类中都有同名的属性时,在子类中若要使用父类的属性时,可以使用super.属性。(2)super只能应用在成员方法和构造方法中。
2.使用super关键字注意事项:
(1) 当子类和父类都有同名的属性时,在子类中如果要使用父类的属性 super.属性
(2) super只能应用在成员方法和构造方法中,不能应用在静态方法中(和this是一样的)
(3) 如果在构造方法中使用必须放在第一行
(4) 在构造方法中this()和super()不能同时出现
补充:super和this对比
No 对比点 this super
1 | 访问属性 | 首先在子类中查找,如果没有就在 父类中查找 | 直接查找父类 |
2 | 访问方法 | 先在子类在中找,如果没有就去父类中查找 | 直接访问父类中方法 |
3 | 调用构造 | 调用本类中的其他构造方法 | 调用父类的构造方法 |
4 | 特殊 | 指自身的对象 | 没有 |
5 | 作为参数 | 可以作为参数 | 没有 |
四种访问权限
1对类中属性和方法的可见度
2.访问修饰符:
private
[default]:包级别访问权限
protected
public
3.类的访问修饰符
·public:任何包中的类都可以访问
·默认值:同一个包中的类可以访问
4.成员访问修饰符:
·private:只对本身类可见
·默认值:同一包中的类可见
·Protected:对所有子类和统一包中的类可见
·Public:对一切类可见
5.在java中可以对类,类的属性以及类的方法前加一个修饰符来对类进行一些访问上的控制
**default,public等可以用来修饰一个类
表格解释:
修饰符 | 同一个类中 | 同一个包中 | 子类中 (不同包) | 全局 |
private | Yes | |||
default | Yes | Yes | ||
Protected | Yes | Yes | Yes | |
public | Yes | Yes | Yes | Yes |
例:
right类:
package right;
public class Person {
String name;
int age;
protected String sex;
}
测试类:
package right;
public class TestDefault {
public static void main(String[] args) {
Person per=new Person();
per.name="朱可夫";
per.age=20;
}
}
right2类:
package right2;
import right.Person;
public class Student extends Person{
public void say(){
// 在子类中可以跨包访问父类的protected属性
System.out.println("性别是:"+this.sex);
}
}
测试类:
package right2;
import right.Person;
public class TestDefault {
public static void main(String[] args) {
Person per=new Person();
}
}
七.方法重写(override)
1. 当子类继承父类时,可以从父类继承它的属性和方法,如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫做方法的重写(override)
2.方法重写规则:
(1)只能用于子类和父类之间
(2)子类的方法名称、输入参数和返回值类型完全一致或子类方法返回值类型是父类方法返回值类型的子类。
(3)子类的权限不能比父类的更加严格
*注意:重写的前提是子类先继承了父类的方法
例1:
Student类:
package org.show;
public class Student {
String name;
String sex;
double Sorce;
public Student() {
super();
}
public Student(String name, String sex, double sorce) {
super();
this.name = name;
this.sex = sex;
Sorce = sorce;
}
public void show(){
System.out.println("同学一:");
System.out.println("我叫"+this.name+",性别"+this.sex+",考了"+this.Sorce+"分!!!!!");
}
}
Student02类;
private int age;
public Student02() {
super();
}
public Student02(int age) {
super("张三","男",99);
this.age = age;
}
public void show(){
System.out.println("同学二:");
System.out.println("我叫"+name+",性别"+sex+",年龄"+this.age+",考了"+Sorce+"分!!!!!");
}
}
StudentTest类:
package org.show;
public class StudentTest {
public static void main(String[] args) {
Student stu=new Student("李四","男",78);
Student02 st2=new Student02(18);
stu.show();
System.out.println("~~~~~~~~~~~~~");
st2.show();
}
}
此例中实现了show方法的重写
**补充-单例设计模式(重要)
1.单例模式分类:
(1)“饿汉式“单例:当类加载到JVM时,单例对象直接创建
(2)懒汉式”单例模式:当类加载到JVM时,并不直接创建单例对象,用户请求单例对象时(用户需要使用时),才实例化该单例对象;
2.私有化构造方法
3.在类的内部实例化该类的对象(该类的对象必须是static全局变量)
例1:饿汉式单例模式:
package single;
/*
* “饿汉式”单例模式:当类加载到JVM时,单例对象直接创建
* */
public class HungrySingleInstance {
// 在该类内部实例化对象
private static HungrySingleInstance single=new HungrySingleInstance();
// 私有化构造方法,防止外部实例化该类的对象
private HungrySingleInstance(){
}
例2:懒汉式单例模式
package single;
/*
* “懒汉式”单例模式:当类加载到JVM时,并不直接创建单例对象,用户请求单例对象时(用户需要使用时),才实例化该单例对象
* */
public class LazySingleInstance {
// 在该类内部实例化对象
private static LazySingleInstance single;
// 私有化构造方法,防止外部实例化该类的对象
private LazySingleInstance(){
}
小结:
·面向对象的已学的特征有:封装性,继承性
·单例设计模式分为:饿汉式设计模式,懒汉式设计模式
·关键字:this,super,static
·四大访问权限:默认值,public,Protected,private
·类与对象的关系及意义
·方法对的重写及方法的重载
【2017.12,12】
原文地址:http://blog.51cto.com/13501268/2050005