Java基础(二)面向对象(上)
面向对象基础知识
面向对象是相对面向过程而言的 面向对象和面向过程都是一种思想 面向过程强调的是功能行为 面向对象将功能封装进对象,强调具备了功能的对象 面向对象是基于面向过程的
面向对象的特征:
- 封装
- 继承
- 多态
java中用类Class来描述事物: 属性:对应类中的成员变量 行为:对应类中的成员函数
成员变量 成员变量定义在类中,在整个类中都可以被访问 成员变量随着对象的建立而建立,存在于对象所在的堆内存中 成员变量有默认初始化值
局部变量 局部变量之定义在局部范围内,如函数内 局部变量存在栈内存中 作用的范围结束,变量空间会自动释放 局部变量没有默认初始化值
匿名对象 匿名对象是对象的简化形式 匿名对象有两种使用情况: 当对象方法仅进行一次调用时 匿名对象可以作为实际参数进行传递
heap-stack
java -x 输出java的非标准选项 java -Xss<size> xxx 设置stack大小 如:java -Xss521k
java -Xmx 设置堆最大值 java -Xms 设置堆初始值
java中对象和数组都位于堆内存中,局部变量函数参数等都位于栈内存中
封装
封装是指隐藏对象的属性和实现细节,仅对外提供公共访问方式
封装原则: 将不需要对外提供的内容都隐藏起来 把属性都隐藏起来,提供公共方法对其访问
代码例子:
package study_java.ex01;
public class ClassDemo1 {
public static void main(String[] args){
Man man = new Man();
// 不能直接通过man访问到money,只能通过getMoney方法
System.out.println(man.getMoney());
man.addMoney(100);
System.out.println(man.getMoney());
// 对于public的变量我们可以直接通过man访问
System.out.println(man.age);
}
}
class Man{
private int money = 100;
public int age = 23;
// 通过封装的方式获取money
public int getMoney(){
return money;
}
// 通过封装的方式修改money
public void addMoney(int num){
money += num;
}
}
private关键字
是一个权限修饰符 用于修饰成员变量和成员函数 被私有化的成员只在本类中有效
常用于: 将成员变量私有化,对外提供对应的set,get方法对其进行访问,提高对数据访问的安全性
构造函数
函数名与类名相同 不用定义返回值类型 没有具体的返回值
作用:给对象进行初始化
package study_java.ex01;
public class ConstructDemo1 {
public static void main(String[] args){
Dog d = new Dog("aa");
d.watch();
}
}
class Dog{
private String name;
private String color;
// 构造函数
public Dog(String n){
name = n;
System.out.println("new Dog()");
}
public void watch(){
System.out.println("旺旺");
System.out.println(name);
}
}
构造代码块也是类成员,是为构造函数添加共有的一些内容 并且构造函数先于构造函数执行
对象的创建过程: 当new一个对象的时候
- 在内个存中分配内存空间
- 对成员变量赋默认值
- 执行构造代码块或赋值语句,执行顺序从上到下执行
- 构造函数
静态代码块
使用static修饰的代码构造块,在类加载的时候调用一次,以后不再调用。 通常放置对静态成员的初始化过程
static成员,跟对象无关,访问的方式是通过Class.XXX()
this关键字
this:代表其所在函数所属对象的引用,即this代表类对象的引用
static 关键字
用于修饰成员(成员变量和成员函数)
被修饰后的成员具备以下特点: 随着类的加载而加载 优先于对象存在 被所有的对象所共享 可以直接被类名调用
使用注意: 静态方法只能访问静态成员 静态方法不能写this,super关键字 主函数是静态的
代码例子如下:
package study_java.ex01;
public class StaticDemo1 {
public static void main(String[] args){
System.out.println(Benz.brand1);
Benz b1 = new Benz();
System.out.println(b1.getBrand());
// 直接访问静态方法
System.out.println(Benz.getBrand1());
}
}
class Benz{
// 静态成员
private static String brand = "BENZ";
public static String brand1 = "BENZ1";
private String color;
public void setColor(String color){
this.color = color;
}
public String getBrand(){
return brand;
}
public static String getBrand1(){
return brand;
}
}
this(): 调用其他构造函数的方式,而且必须作为第一条语句
继承
多个类中存在相同的属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继承那个类即可。
多个类可以称为子类,单独这个类称为父类 子类可以直接访问父类中国非私有的属性和方法 通过extends关键字让类与类之间产生继承 java中只支持单冲继承 + 多层继承
简单的例子:
package study_java.ex01;
public class ExtendsDemo1 {
public static void main(String[] args){
JingBa jingba = new JingBa();
jingba.name = "大黄";
jingba.watch();
jingba.owner="zz";
}
}
class Animal{
public String name;
public int weight;
public void move(){
System.out.println("move.....");
}
}
class Dog extends Animal{
public void watch(){
System.out.println("有人来了");
}
}
class JingBa extends Dog{
public String owner;
}
super关键字
调用的是父类的构造函数,必须是第一条语句 通过下面例子理解:
package study_java.ex01;
public class ExtendsDemo2 {
public static void main(String[] args){
// 创建对象
BMWSportCar mychar = new BMWSportCar();
mychar.color = "red";
mychar.velocity = 200;
mychar.price = 20000;
mychar.run();
}
}
class Car{
public String color;
public void run(){
System.out.println("running.....");
}
public Car(String color){
this.color = color;
System.out.println("new car("+color+")");
}
}
class SportCar extends Car{
public int velocity;
public SportCar(int velocity){
super("yellow");
this.velocity = velocity;
System.out.println("new SportCar("+velocity +")");
}
}
class BMWSportCar extends SportCar{
public int price;
public BMWSportCar(){
super(200);
System.out.println("new BMWSportCar");
}
}
如果被继承的父类的属性是私有的,如果想要访问或者更改,可以通过定义公有的方法来实现,代码例子如下:
package study_java.ex01;
public class ExtendsDemo2 {
public static void main(String[] args){
// 创建对象
BMWSportCar mychar = new BMWSportCar();
mychar.setColor("red");
mychar.velocity = 200;
mychar.price = 20000;
mychar.run();
System.out.println(mychar.getColor());
}
}
class Car{
//私有属性
private String color;
public void run(){
System.out.println("running.....");
}
public Car(){
System.out.println("new car()");
}
// 公有方法
public String getColor(){
return color;
}
public void setColor(String color){
this.color = color;
}
}
class SportCar extends Car{
public int velocity;
public SportCar(){
System.out.println("new SportCar()");
}
}
class BMWSportCar extends SportCar{
public int price;
public BMWSportCar(){
System.out.println("new BMWSportCar");
}
}
super和this的用法有点相似
- this代表本类对象的引用
- super代表父类的内存空间的标识
- 子类要调用父类构造函数时,可以使用super()语句
- 当子类和父类出现同名成员时,可以用super进行区分
super()和this()
调用父类的构造函数,必须是第一条语句
package study_java.ex01;
public class ExtendsDemo2 {
public static void main(String[] args){
// 创建对象
BMWSportCar mychar = new BMWSportCar();
mychar.setColor("red");
mychar.velocity = 200;
mychar.price = 20000;
mychar.run();
System.out.println(mychar.getColor());
}
}
class Car{
//私有属性
private String color;
public void run(){
System.out.println("running.....");
}
public Car(){
System.out.println("new car()");
}
// 公有方法
public String getColor(){
return color;
}
public void setColor(String color){
this.color = color;
}
}
class SportCar extends Car{
public int velocity;
public SportCar(){
System.out.println("new SportCar()");
}
public void setColorPro(String color){
// this.color = color; //这里和下面的的super是一样的
super.setColor(color);
}
public void setColor(String color){
super.setColor(color);
}
}
class BMWSportCar extends SportCar{
public int price;
public BMWSportCar(){
System.out.println("new BMWSportCar");
}
}
任何一个对象的创建都包含整个家族簇的创建,任何一个成员的创建,都包含这一整个顺序的完成 通过下面代码理解这个过程
package study_java.ex01;
public class ExtendsDemo3 {
public static void main(String[] args){
// 创建对象
BMWSportCar mychar = new BMWSportCar();
mychar.setColor("red");
mychar.velocity = 200;
mychar.price = 20000;
mychar.run();
System.out.println(mychar.getColor());
}
}
class Car{
//私有属性
private String color;
{
System.out.println("Cons Block in Car");
}
public void run(){
System.out.println("running.....");
}
public Car(){
System.out.println("new car()");
}
// 公有方法
public String getColor(){
return color;
}
public void setColor(String color){
this.color = color;
}
}
class SportCar extends Car{
public int velocity;
{
System.out.println("Cons Block in SportCar");
}
public SportCar(){
System.out.println("new SportCar()");
}
public void setColor(String color){
super.setColor(color);
}
}
class BMWSportCar extends SportCar{
public int price;
public BMWSportCar(){
System.out.println("new BMWSportCar");
}
}
函数覆盖
子类中出现与父类中一模一样的方法时,会出现覆盖操作,也称为重写或者复写 父类中的私有方法不可以被覆盖 在子类覆盖方法中,继续使用被覆盖的方法可以通过super函数名获取
覆盖时需要注意的问题: 覆盖时,子类方法权限一定要大于等于父类方法权限 静态只能覆盖静态
主要的应用是: 当子类需要父类的功能,而功能主题子类有自己特有的内容时,可以复写父类中的方法,这样就既沿袭了父类 的功能,又定义了父类特有的内容
代码例子:
package study_java.ex01;
public class OverrideDemo1 {
public static void main(String[] args){
Rich2Man s2 = new Rich2Man();
s2.consume(200000);
}
}
class RichMan{
public void consume(int money){
if(money < 500){
System.out.println("消费了"+money+"w");
}
else {
System.out.println("不能消费了");
}
}
}
class Rich2Man extends RichMan{
public void consume(int money){
if(money < 50000){
System.out.println("消费了"+money+"w");
}
else {
System.out.println("不能消费了");
}
}
}
子类的实例化过程
子类中所有的构造函数morning都会访问父类中空参数的构造函数 因为每一个构造函数的第一行都有一条默认的语句super() 子类会具备父类中的数据,所以要先明确父类是如何对这些数据初始化的。 当父类中没有空参数的构造函数时,子类的构造函数必须通过this或者super语句指定要访问的构造函数
final 关键字
final 可以修饰类,方法和变量
final 修饰的类不可以被继承
final 修饰的方法不可以被覆盖(可以继承)
final 修饰的变量是一个常量只能被赋值一次
内部类只能访问被final修饰的局部变量
package study_java.ex01;
public class FinalDemo1 {
public static void main(String[] args){
Jing8 j = new Jing8();
j.watch();
System.out.println(j.name);
}
}
class Dog1{
// 常量
public final String name = "aaa";
// final 修饰的方法不能重写
public /*final */ void watch(){
System.out.println("来人了");
}
}
class Jing8 extends Dog1{
public void watch() {
System.out.println("听一听");
super.watch();
}
}
关于内部类 定义在class内部的类 编译产生OuterClass$Innerc.class 内部类访问外部类的局部变量,需要final修饰
代码例子:
package study_java.ex01;
public class InnerClassDemo {
public static void main(String[] args){
Car2 c = new Car2();
c.run();
}
}
class Car2{
public String color = "red";
public int tires;
public void run(){
new Engine().fire();
System.out.println("running.....");
}
class Engine{
public void fire(){
System.out.println("fire");
}
}
}
但是如果内部类写在了方法里,这里有一个问题需要注意:
public class InnerClassDemo {
public static void main(String[] args){
Car2 c = new Car2();
c.run();
}
}
class Car2{
public String color = "red";
public int tires;
public void run(){
// 这里的key必须是final 字段
final String key = "ss";
class Engine{
public void fire(){
System.out.println("插入钥匙"+key);
System.out.println("fire");
}
}
new Engine().fire();
System.out.println("running.....");
}
}
抽象类
抽象类的定义: 抽象就是从多个事物中将共性的,本质的内容抽取出来 java 中可以定义没有方法体的方法,该方法的具体实现交给子类完成该 方法称为抽象方法,包含抽象方法的类就是抽象类
抽象类和抽象方法必须用abstract关键字修饰 抽象方法只有方法声明,没有具体的方法体,定义在抽象类中 抽象类不可以被实例化,也就是不能用new创建对象 抽象类通过其子类实例化,而子类需要覆盖掉抽象类中所有的方法后才可以创建对象,否则该子类也是抽象类
Java基础(二)面向对象(上)的更多相关文章
- 【Java基础】面向对象上
面向对象上 这一章主要涉及 Java 类及类的成员,包括属性.方法.构造器:代码块.内部类. 面向过程与面向对象 面向过程(Procedure Oriented Programming,POP)与面向 ...
- Java入土--Java基础(二)
Java基础(二) 接上一讲,我们接着来聊聊Java的一些基础知识,下一讲就会进行流程的控制. 类型转换 首先呢,是类型的转换,接上一个内容的数据类型,类型转换就是数据类型更进一步的应用. 由于Jav ...
- 20175212童皓桢 Java实验二-面向对象程序设计实验报告
20175212童皓桢 Java实验二-面向对象程序设计实验报告 实验内容 初步掌握单元测试和TDD 理解并掌握面向对象三要素:封装.继承.多态 初步掌握UML建模 熟悉S.O.L.I.D原则 了解设 ...
- Java基础-初识面向对象编程(Object-Oriented-Programming)
Java基础-初识面向对象编程(Object-Oriented-Programming) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. Java是一门面向对象的程序设计语言.那么什 ...
- Java面试题总结之Java基础(二)
Java面试题总结之Java基础(二) 1.写clone()方法时,通常都有一行代码,是什么? 答:super.clone(),他负责产生正确大小的空间,并逐位复制. 2.GC 是什么? 为什么要有G ...
- 黑马程序员——【Java基础】——面向对象(二)异常机制、包(Package)
---------- android培训.java培训.期待与您交流! ---------- 一.异常机制 (一)异常概述 1.异常:就是程序在运行时出现不正常情况. 2.异常类:程序在运行时,出现的 ...
- Java基础知识【上】(转载)
http://blog.csdn.net/silentbalanceyh/article/details/4608272 (最终还是决定重新写一份Java基础相关的内容,原来因为在写这一个章节的时候没 ...
- Java基础(二) 基本类型数据类型、包装类及自动拆装箱
我们知道基本数据类型包括byte, short, int, long, float, double, char, boolean,对应的包装类分别是Byte, Short, Integer, Long ...
- 最新28道java基础面试题-上
28道java基础面试题 1.面向对象的特征有哪些方面? 答:面向对象的特征主要有以下几个方面: 抽象:抽象是将一类对象的共同特征总结出来构造类的过程,包括数据抽象和行为抽象两方面.抽象只关注对象有哪 ...
- java基础(二)-----java的三大特性之继承
在<Think in java>中有这样一句话:复用代码是Java众多引人注目的功能之一.但要想成为极具革命性的语言,仅仅能够复制代码并对加以改变是不够的,它还必须能够做更多的事情.在这句 ...
随机推荐
- python数据结构之冒泡排序
冒泡排序是一种基础排序算法,在python中,我们利用列表的的方式来完成,它对列表中的元素进行重复的遍历,在遍历的同时进行比较,如果两个数没有按照我们规定的顺序进行排列,就按照我们预先设定好的是顺序或 ...
- BZOJ-2-4870: [Shoi2017]组合数问题 矩阵优化 DP
就 是 要 我 们 从 n k 件 物 品 里 面 选 出 若 干 件,使 得 其 数 量 模 k 等 于 r 的 方 案 数 . dp方程 f [ i , j ] 表示前 i 件物品拿了若干件使 ...
- 将ant Design本地化,可通过link以及script直接引入html中使用
一直想着能本地化antd的,不用npm以及dva那么复杂的配置环境来开发,并且本地化以后对以后链接flask的模板渲染机制也能很好的结合.下面是具体的实现方法: 1.将react的相关链接引入: &l ...
- IE8 兼容性总结
rgba 颜色格式 IE8 不支持 rgba(0, 0, 0, .5) 这种颜色格式. 解决方案:可以利用一张半透明的 png 图片来兼容 IE8. flexbox 根据 caniuse 给出的数据, ...
- 关于visual assist x插件不能用的解决方案
打開VS莫名其妙地彈出下面的錯誤框: "the security key for this program currently stored on your system does not ...
- JQuery POST请求封装
_uri_api = function(url){ return 'http://localhost/msquare/' + url; // return 'http://test2.msqsoft. ...
- 转载 转载 转载 数组a[],a,&a之间的区别
通俗理解:内存就是公寓房间,指针就是房间的门牌号,数组就是连续的公寓房间,数组名就是这组连续房间的起始地址,也就是第一个房间的地址. 例如int a[5] a是数组名,也就是第一个房间号 & ...
- C++程序设计方法2:函数运算符重载
函数运算符()重载 函数运算符()也能重载,它使得对象看上去像是一个函数名 ReturnType operator() (Parameters) { ...... } ClassName Obj; O ...
- yii2 动态配置日志(log)
如果我们在项目中不允许修改配置文件中的 log 组件,那么动态配置 log 就变得很重要了,下面我分享一下动态配置 log 的方法: 默认的日志格式是 {date}{ip}{userID}{sessi ...
- 使用html5 Canvas绘制线条(直线、折线等)
使用html5 Canvas绘制直线所需的CanvasRenderingContext2D对象的主要属性和方法(有"()"者为方法)如下: 属性或方法 基本描述 strokeSty ...