When i set the true value but error what's am wrong with this code
Original
".field private isPro:Z"
My set
'''.field private isPro:Z=true'''
In smali/dalvik "Z" means "boolean", in your case it is defining only the type, not the value:
.field private isPro:Z
Changing "Z" to "true" will not work, since "true" it is not a valid type.
If you want to change its value, you need to search where the variable isPro is used, and change/override from 0x0 (false) to 0x1 (true).
you should use iput-boolean in constructor or any method instead of assign directly when defining field.
.field private isPro:Z
#assign value
const/4 v0, 0
iput-boolean v0, p0, Lcom/example/YourClassPath;->isPro:Z
btw, direct assign only works in static field like below
# not 0 not 1
.field private static isPro:Z = true
Related
I've tried to create a vb scripts class with a constant and got 800A03EA error. It's it a VBS bug? Isn't it an OOP fundamental rule?
Class customer
' comment it const and its works
const MAX_LEN=70
Private Name
Private Sub Class_Initialize
Name = ""
End Sub
' name property.
Public Property Get getName
getName = Name
End Property
Public Property Let letName(p_name)
Name = p_name
End Property
end class
The documentation lists all statements that are allowed in the context of classes. Const isn't among them, so it's not supported. You can work around the issue by using private member variables that you initialize during instantiation (i.e. in Class_Initialize):
Class customer
Private MAX_LEN
Private Name
Private Sub Class_Initialize
MAX_LEN = 70
Name = ""
End Sub
...
End Class
If instances of the class should expose this value, you could implement it as a read-only property:
Class customer
Private MAX_LEN
Private Sub Class_Initialize
MAX_LEN = 70
End Sub
'read-only property, so no "Property Let/Set"
Public Property Get MaxLength
MaxLength = MAX_LEN
End Property
...
End Class
However, as Ekkehard.Horner pointed out correctly, the value could still be changed by object-internal code. If immutability is the primary requirment for this value you should implement it as a global constant.
I agree with Ansgar Wiechers's answer, but would like to propose another option.
If immutability is more important than performance, you could put the value directly in the Get and use the property to refer to the value instead of a class-level variable.
Class customer
'read-only property, so no "Property Let/Set"
Public Property Get MaxLength
MaxLength = 70
End Property
...
End Class
A Private variable (perhaps with a getter) gives you a value that is read-only from the outside of the class, but class internal code can still change that value.
So using a global Const (perhaps with a 'namespace' name part) may be a better workaround in cases where the constness is most important.
I made a class in VBScript and used it in asp classic to instatiate an object:
This is my class:
<%
Class RBAC
Public dateTimeValue
Public userIdValue
Public fileIdValue
Public actionValue
Public Property Get DateTime()
'Gets the propery value
DateTime = dateTimeValue
End Property
Public Property Set DateTime(value)
'Sets the property value
dateTimeValue = value
End Property
Public Property Get UserId()
'Gets the propery value
UserId = userIdValue
End Property
Public Property Set UserId(value)
'Sets the property value
userIdValue = value
End Property
Public Property Get FileId()
'Gets the propery value
FileId = fileIdValue
End Property
Public Property Set FileId(value)
'Sets the property value
fileIdValue = value
End Property
Public Property Get Action()
'Gets the propery value
Action = actionValue
End Property
Public Property Set Action(value)
'Sets the property value
actionValue = value
End Property
Public Sub Insert()
sqlMethods = "INSERT INTO RBAC ([DateTime],[UserId],[FileId],[Action]) VALUES ("+dateTimeValue+","+userIdValue+","+fileIdValue+","+actionValue+",)"
Conn.Execute(sqlMethods)
End Sub
End Class
%>
And here I instantiate an object and set it's properties:
Dim RbacObject
Set RbacObject = New RBAC
Set RbacObject.DateTime = Now
Set RbacObject.UserId = Cstr(Session("cgsid"))
sqlFileId = "SELECT int_fileid FROM tbl_SecFiles where str_filename = '"&split(Request.ServerVariables("SCRIPT_NAME"),"/cgs/")(1)&"'"
Set RS = Conn.Execute(sqlFileId)
Set RbacObject.FileId = RS("int_fileid")
Set RbacObject.Action = "<"&stringMethods&"><old>"&enabled_profiles_old&"</old><new>"&enabled_profiles_old&siteid&",</new></"&stringMethods&">"
RbacObject.Insert
The problem is that only FileId gets a value rest of the fields are empty, even if I set them an value. What am I doing wrong?
Set is used for assigning objects to variables. So
Set RbacObject = New RBAC
is correct, but all other statements like
Set RbacObject.DateTime = Now
are not. Use
RbacObject.DateTime = Now
instead.
Set RbacObject.FileId = RS("int_fileid")
is a borderline case: fileIdValue will contain a Field object, but evaluate to its .Value when used in a 'non-object context' (like IO or computations).
You shouldn't run dubious code with/under On Error Resume Next.
Demo:
copy con 10.vbs
Class C
Public V
End Class
Set O = New C
Set O.V = "don't do this at home."
^Z
cscript 10.vbs
... 10.vbs(5, 1) Microsoft VBScript runtime error: Object required: 'O.V'
Demo II (to prove that 'it works' if you don't use Set for assignment of non-objects, and indicate that there must be other error hidden by the evil OERN if it 'still doesn't work'):
Class C
Public V
End Class
Set O = New C
On Error Resume Next
Set O.V = "don't do this at home."
WScript.Echo Err.Description
On Error GoTo 0
WScript.Echo "Set O.V => '" & O.V & "'"
O.V = "don't do this at home."
WScript.Echo "O.V => '" & O.V & "'"
output:
cscript 10.vbs
Object required
Set O.V => ''
O.V => 'don't do this at home.'
In addition to what Ekkehard.Horner said you need to define the setters for properties that don't take objects as
Public Property Let name(value)
not as
Public Property Set name(value)
I have been trying to implement a very simple tree structure in VBA for some basic text parsing needs. The relevant code follows.
Private pLeaves() As CTree
Private numLeaves As Integer
Private leavesLen As Integer
Private iterate As Integer
Private pParent As CTree
Public pValue As Object
Public Sub class_initialize()
ReDim pLeaves(10)
leavesLen = 10
numLeaves = 0
Set pParent = Nothing
iterate = 0
Set pValue = Nothing
End Sub
Public Sub Class_terminate()
'We'll leave it empty for now
'if it looks like it's not working right we might change it
End Sub
Public Property Get Parent() As CTree
Parent = pParent
End Property
Public Property Get Leaves() As CTree
Leaves = pLeaves
End Property
Private Property Set Parent(ByRef p As CTree)
Set pParent = p
End Property
Private Property Set value(ByRef value As Object)
Set pValue = value
End Property
Public Sub Add_Leaf(ByRef value As Object)
Dim n As Integer
n = numLeaves
If numLeaves >= leavesLen Then
ReDim Preserve pLeaves(leavesLen + 10)
leavesLen = leavesLen + 10
End If
Set pLeaves(n) = New CTree
Set pLeaves(n).Parent = Me
Set pLeaves(n).value = value
End Sub
Public Function DFFind_Leaf(value As Object) As CTree
Dim i As Integer
If pValue = value Then
Set DFFind_Leaf = Me
Return
End If
If numLeaves = 0 Then
Set DFFind_Leaf = Nothing
Return
End If
For i = 0 To numLeaves
Set DFFind_Leaf = pLeaves(i).DFFind_Leaf(value)
If DFFind_Leaf <> Nothing Then
Return
End If
Next i
Set DFFind_Leaf = Nothing
Return
End Function
When I try to call the Add_Leaf function with an object though I end up getting a
method or data member not found error from VBA on the line where I'm trying to
set pLeaves(n).Parent= me
Any idea what the reason for that might be?
Edit: ok I figured out how to fix this. Changing the set property Parent(...) from private
to public fixed the problem. So apparently I don't quite understand what private exactly does in vba. If someone wants to explain how to do this without essentially exposing the variables for anyone to set as they want I would be grateful.
Private tells the VBA interpreter that the scope of the variable is restricted to the class/module only. You can therefore access it only inside of the original class, but not from the outside. Publicon the other hand allows you to access the variable from the outside.
However, note that when working with classes, it is strongly discouraged to publicly expose any variables. Instead it is best practice to expose so called properties, using the SET PROPERTYand GET PROPERTY keywords.
I.e. instead of
Public Amount as Double
It is often better to use this approach:
Private mAmount as Double
Property Set Amount(amt as Double) 'Note that by default, properties are public
If amt > 0 Then
mAmount = amt
Else
mAmount = 0
End If
End Property
Property Get Amount as Double
Amount = mAmount
End Property
As you can see from this example, the advantage is that you can actually add additional verifications/modifications and therefore ensure the consistency.
In your example, you could consider to simply provide a method, i.e. a public sub, that adds a leave and takes care of all the settings, e.g.
Public Sub AddLeave(strName as String)
Dim objLeave as New CTree
objLeave.Init strName, Me
mLeaves.Add objLeave, strName
End Sub
Public Sub Init(strName as String, objParent as CTree)
Me.Name = strName
Set Me.Parent = objParent
End Sub
I'm trying to create a class module to build some basic db functionality in a workbook. The problem I'm running into is attempting to add a worksheet as a class member. I keep getting "Invalid use of property" as an error.
My class declaration:
Option Explicit
Private pboolLock As Boolean
Private pintColCount, pintRowCount As Integer
Private pWorksheet As Excel.Worksheet
'Lock bit properties:
Property Get boolLock() As Boolean
boolLock = pboolLock
End Property
Property Let boolLock(boollockval As Boolean)
pboolLock = boollockval
End Property
'Utility properties- no sets
Property Get ColCount() As Integer
ColCount = pintColCount
End Property
Property Get RowCount() As Integer
RowCount = pintRowCount
End Property
'Worksheet specific props
Property Set dpDefine(ByRef wks As Worksheet)
Set pWorksheet = wks
End Property
Property Get dpDefine() As Worksheet
dpDefine = pWorksheet
End Property
Different module: Class instantiation:
Sub tryClass()
Dim thisdp As New Cdatapage
Dim iansTest As String
iansTest = Sheets("typical datapage").Name
'this works, so reference is being passed:
MsgBox ("The name is " & iansTest)
'this doesn't work:
thisdp.dpDefine (Sheets("typical datapage"))
End Sub
Any suggestions? Thanks.
Its a Set property so you need to:
Set thisdp.dpDefine = Sheets("typical datapage")
Or if you change dpDefine to a Let you can;
thisdp.dpDefine = Sheets("xxx")
I have created two classes as interface / implementation classes, and wish to pass a particular example of one class to a method in the other. The definitions are as follows...
Class BigInt...
Option Explicit
Public Sub dothing(ByRef passed_object As MyInt)
End Sub
and an implementation BigImplementation...
Option Explicit
Implements BigInt
Public Sub BigInt_dothing(ByRef passed_obj As MyInt)
Dim i As Integer
i = passed_obj.getprop
End Sub
The class I am planning to pass is...
Option Explicit
Public Property Get getprop() As Integer
End Property
Public Property Let letprop(ByVal myval As Integer)
End Property
implemented as MyImplementation thus...
Option Explicit
Implements MyInt
Private myval As Integer
Public Property Get myint_getprop() As Integer
myint_getprop = myval
End Property
Public Property Let myint_letprop(ByVal passed_int As Integer)
myval = passed_int
End Property
I am then driving this with the following snippet of code:-
Private Sub Command_Click()
Dim myobj As MyInt
Set myobj = New MyImplementation
Dim mybigobj As BigInt
Set mybigobj = New BigImplementation
myobj.letprop = 1
Call mysub(myobj)
mybigobj.dothing (myobj) ' Line with problem
End Sub
Private Sub mysub(ByVal passed_obj As MyInt)
Dim i As Integer
i = passed_obj.getprop
End Sub
When the execution reaches the line marked, I get run-time error 438 - Object doesn't support property or method. The call to the ordinary function mysub works perfectly. Does anyone know what I am doing wrong and what I need to do to fix this?
Use either
mybigobj.dothing myobj
or
Call mybigobj.dothing(myobj)
Putting extra parentheses around a reference evaluates its default property and passes it's value as actual argument.
mybigobj.dothing requires its parameter to be a MyInt
Public Sub BigInt_dothing(ByRef passed_obj As MyInt)
Dim i As Integer
i = passed_obj.getprop
End Sub
You're passing a MyImplementation
Set myobj = New MyImplementation
So possiblly something like (my vb is rusty)
mybigobj.dothing (myobj.myint_getprop())